Dec 20th, 2002, 11:41 AM
#1
Thread Starter
Frenzied Member
Type Cast Error
This is the error I get with the ListView_SortItems() macro:
Code:
Compiling...
CListView.cpp
C:\Documents and Settings\youngwe\Desktop\ListViewold\ListView\ListView\CListView.cpp(87) : error C2440: 'type cast' : cannot convert from '' to 'int (__stdcall *)(long,long,long)'
None of the functions with this name in scope match the target type
Error executing cl.exe.
Code:
// CListView.h
#ifndef __CLISTVIEW_H__
#define __CLISTVIEW_H__
#include <windows.h>
#include <commctrl.h>
class CListView
{
protected:
bool bSortAscend;
int nColumns;
int nLastCol;
LVCOLUMN lvColumn;
LVITEM lvItem;
LVITEM lvFindItem;
LVFINDINFO lvFindInfo;
NMLISTVIEW *nmListView;
HWND hWndListView;
INITCOMMONCONTROLSEX initCommCtls;
public:
CListView();
void SetHwnd(HWND& hWnd, int nIDDlgItem);
void SetColumns(int nCount, int nSize[], char* szText[]);
void InsertRow(char* szText[]);
void SortItems(LPARAM lParam);
INT CALLBACK CompareString(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort);
};
#endif // __CLISTVIEW_H__
Code:
// CListView.cpp
#include "CListView.h"
CListView::CListView()
{
initCommCtls.dwICC = ICC_LISTVIEW_CLASSES;
initCommCtls.dwSize = sizeof(INITCOMMONCONTROLSEX);
InitCommonControlsEx(&initCommCtls);
lvColumn.mask = LVCF_TEXT | LVCF_WIDTH;
lvItem.mask = LVIF_TEXT | LVIF_PARAM;
lvItem.iSubItem = 0;
nColumns = 0;
bSortAscend = false;
}
void CListView::SetHwnd(HWND& hWnd, int nIDDlgItem)
{
hWndListView = GetDlgItem(hWnd, nIDDlgItem);
}
void CListView::SetColumns(int nCount, int nSize[], char* szText[])
{
nColumns = nCount;
for(int i = 0; i < nCount; i++)
{
lvColumn.cx = nSize[i];
lvColumn.pszText = szText[i];
ListView_InsertColumn(hWndListView, i, &lvColumn);
}
}
void CListView::InsertRow(char* szText[])
{
int nCount = ListView_GetItemCount(hWndListView);
lvItem.iItem = lvItem.lParam = nCount;
lvItem.pszText = szText[0];
ListView_InsertItem(hWndListView, &lvItem);
for(int i = 1; i < nColumns; i++)
{
ListView_SetItemText(hWndListView, nCount, i, szText[i]);
}
}
void CListView::SortItems(LPARAM lParam)
{
nmListView = (LPNMLISTVIEW)lParam;
if(nmListView->hdr.code == LVN_COLUMNCLICK)
{
if(nLastCol != nmListView->iSubItem)
{
bSortAscend = false;
}
ListView_SortItems(nmListView->hdr.hwndFrom,
/*problems here ------>*/ (PFNLVCOMPARE)CompareString, nmListView->iSubItem);
if(bSortAscend)
{
bSortAscend = false;
}
else
{
bSortAscend = true;
}
}
}
INT CALLBACK CListView::CompareString(LPARAM lParam1, LPARAM lParam2,
LPARAM lParamSort)
{
char szText1[32];
char szText2[32];
int iIndex;
lvFindInfo.lParam = lParam1;
iIndex = ListView_FindItem(hWndListView, -1, &lvFindInfo);
ListView_GetItemText(hWndListView, iIndex, (INT)lParamSort, (LPTSTR)szText1, 16);
lvFindInfo.lParam = lParam2;
iIndex = ListView_FindItem(hWndListView, -1, &lvFindInfo);
ListView_GetItemText(hWndListView, iIndex, (INT)lParamSort, (LPTSTR)szText2, 16);
if(bSortAscend)
{
return -strcmp(szText1, szText2);
}
else
{
return strcmp(szText1, szText2);
}
return 0;
}
Code:
// main.cpp
#include "CListView.h"
#include "resource.h"
CListView cList;
BOOL CALLBACK DialogProc(HWND hWnd, UINT uMsg,
WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_INITDIALOG:
{
cList.SetHwnd(hWnd, IDC_LIST1);
char* szText[3] = {"Column 1", "Column 2", "Column 3"};
int nSize[3] = {100, 75, 75};
cList.SetColumns(3, nSize, szText);
szText[0] = "aaaaxkkjlj";
szText[1] = "04/24/2002";
szText[2] = "99";
cList.InsertRow(szText);
szText[0] = "edkkljkjk";
szText[1] = "10/18/2002";
szText[2] = "11";
cList.InsertRow(szText);
szText[0] = "kjdkdjdkdj";
szText[1] = "07/29/1977";
szText[2] = "22";
cList.InsertRow(szText);
ShowWindow(hWnd, SW_SHOW);
break;
}
case WM_CLOSE:
{
PostQuitMessage(0);
break;
}
case WM_NOTIFY:
{
cList.SortItems(lParam);
break;
}
default:
{
return FALSE;
}
}
return FALSE;
}
INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpszArgument, INT iCmdShow)
{
MSG msg;
HWND hWndDialog;
hWndDialog = CreateDialog(hInstance, (LPCTSTR)IDD_DIALOG1, NULL, (DLGPROC)DialogProc);
while(GetMessage(&msg, NULL, 0, 0))
{
if(!IsDialogMessage(hWndDialog, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return msg.wParam;
}
What is going on here?
Attached Files
Dec 21st, 2002, 01:01 PM
#2
You shouldn't need a type cast here at all.
By the way: the compiler gave an error because you tried to cast a function to a function pointer. You must use the address-of (&) operator:
Code:
(PFNLVCOMPARE)& CompareString
Dec 21st, 2002, 04:22 PM
#3
Thread Starter
Frenzied Member
Originally posted by twanvl
You shouldn't need a type cast here at all.
By the way: the compiler gave an error because you tried to cast a function to a function pointer. You must use the address-of (&) operator:
Code:
(PFNLVCOMPARE)& CompareString
No, coding it that way causes this error:
Code:
Compiling...
CListView.cpp(76) : error C2276: '&' : illegal operation on bound member function expression
Error executing cl.exe.
ListView.exe - 1 error(s), 0 warning(s)
PFNLVCOMPARE references the function so the & would not be
necessary anyway.
It works several different ways not using classes and just straight
win32 api:
Code:
#include <windows.h>
#include <commctrl.h>
#include "resource.h"
LVCOLUMN lvColumn;
LVITEM lvItem;
LVITEM lvFindItem;
LVFINDINFO lvFindInfo;
NMLISTVIEW *nmListView;
HWND hWndListView;
BOOL bSortAscend = FALSE;
LONG lLastCol = -1;
INT CALLBACK ListViewCompareString(LPARAM lParam1, LPARAM lParam2,
LPARAM lParamSort){
CHAR szText1[16];
CHAR szText2[16];
INT iIndex;
lvFindInfo.flags = LVFI_PARAM;
lvFindInfo.lParam = lParam1;
iIndex = ListView_FindItem(hWndListView, -1, &lvFindInfo);
ListView_GetItemText(hWndListView, iIndex, (INT)lParamSort, (LPTSTR)szText1, 16);
lvFindInfo.lParam = lParam2;
iIndex = ListView_FindItem(hWndListView, -1, &lvFindInfo);
ListView_GetItemText(hWndListView, iIndex, (INT)lParamSort, (LPTSTR)szText2, 16);
if(bSortAscend)
return -strcmp(szText1, szText2);
else
return strcmp(szText1, szText2);
return 0;
}
BOOL CALLBACK DialogProc(HWND hWnd, UINT uMsg,
WPARAM wParam, LPARAM lParam){
switch(uMsg){
case WM_INITDIALOG:
hWndListView = GetDlgItem(hWnd, IDC_LIST1);
// Column Headers
lvColumn.mask = LVCF_TEXT | LVCF_WIDTH;
lvColumn.cx = 100;
lvColumn.pszText = "Column 1";
ListView_InsertColumn(hWndListView, 0, &lvColumn);
lvColumn.pszText = "Column 2";
ListView_InsertColumn(hWndListView, 1, &lvColumn);
lvColumn.pszText = "Column 3";
ListView_InsertColumn(hWndListView, 2, &lvColumn);
// Column 1 Data
lvItem.mask = LVIF_TEXT | LVIF_PARAM;
lvItem.iItem = lvItem.lParam = 0;
lvItem.iSubItem = 0;
lvItem.pszText = "aaaaxeddkd";
ListView_InsertItem(hWndListView, &lvItem);
lvItem.iItem = lvItem.lParam = 1;
lvItem.iSubItem = 0;
lvItem.pszText = "edkadlkajd";
ListView_InsertItem(hWndListView, &lvItem);
lvItem.iItem = lvItem.lParam = 2;
lvItem.iSubItem = 0;
lvItem.pszText = "aaaaaxdkdj";
ListView_InsertItem(hWndListView, &lvItem);
lvItem.iItem = lvItem.lParam = 3;
lvItem.iSubItem = 0;
lvItem.pszText = "zzzjkdjdfkj";
ListView_InsertItem(hWndListView, &lvItem);
// Column 2 Data
ListView_SetItemText(hWndListView, 0, 1, "04/24/2002");
ListView_SetItemText(hWndListView, 1, 1, "10/18/2002");
ListView_SetItemText(hWndListView, 2, 1, "09/12/2002");
ListView_SetItemText(hWndListView, 3, 1, "07/29/2002");
// Column 3 Data
ListView_SetItemText(hWndListView, 0, 2, "99");
ListView_SetItemText(hWndListView, 1, 2, "11");
ListView_SetItemText(hWndListView, 2, 2, "33");
ListView_SetItemText(hWndListView, 3, 2, "55");
ShowWindow(hWnd, SW_SHOW);
break;
case WM_CLOSE:
PostQuitMessage(0);
break;
case WM_NOTIFY:
nmListView = (LPNMLISTVIEW)lParam;
if(nmListView->hdr.code == LVN_COLUMNCLICK){
if(lLastCol != nmListView->iSubItem)
bSortAscend = FALSE;
lLastCol = nmListView->iSubItem;
// either & or PFNLVCOMPARE or both or nothing works here
// though PFNLVCOMPARE is correct
ListView_SortItems(nmListView->hdr.hwndFrom,
(PFNLVCOMPARE)ListViewCompareString, (LPARAM)(nmListView->iSubItem));
if(bSortAscend)
bSortAscend = FALSE;
else
bSortAscend = TRUE;
return 0;
}
break;
default:
return FALSE;
}
return FALSE;
}
INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpszArgument, INT iCmdShow){
MSG msg;
HWND hWndDialog;
INITCOMMONCONTROLSEX initCommCtls;
initCommCtls.dwICC = ICC_LISTVIEW_CLASSES;
initCommCtls.dwSize = sizeof(INITCOMMONCONTROLSEX);
InitCommonControlsEx(&initCommCtls);
hWndDialog = CreateDialog(hInstance, (LPCTSTR)IDD_DIALOG1, NULL, (DLGPROC)DialogProc);
while(GetMessage(&msg, 0, 0, 0)){
if(!IsDialogMessage(hWndDialog, &msg)){
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return msg.wParam;
}
Attached Files
Dec 21st, 2002, 06:36 PM
#4
Wait a minute:
The function you are trying to take the address of is a member of a class. Class member functions differ from normal function, because they also get a this pointer.
The solution to your problem is to either make the ListViewCompareString function static , or to move it outside the class.
Dec 21st, 2002, 07:45 PM
#5
Thread Starter
Frenzied Member
Code:
Compiling resources...
Compiling...
CListView.cpp
CListView.cpp(97) : error C2724: 'CompareStringA' : 'static' should not be used on member functions defined at file scope
CListView.cpp(103) : error C2228: left of '.lParam' must have class/struct/union type
CListView.cpp(104) : error C2597: illegal reference to data member 'CListView::hWndListView' in a static member function
CListView.cpp(104) : error C2440: 'type cast' : cannot convert from 'struct tagLVFINDINFOA CListView::*' to 'const struct tagLVFINDINFOA *'
There is no context in which this conversion is possible
CListView.cpp(105) : error C2597: illegal reference to data member 'CListView::hWndListView' in a static member function
CListView.cpp(107) : error C2228: left of '.lParam' must have class/struct/union type
CListView.cpp(108) : error C2597: illegal reference to data member 'CListView::hWndListView' in a static member function
CListView.cpp(108) : error C2440: 'type cast' : cannot convert from 'struct tagLVFINDINFOA CListView::*' to 'const struct tagLVFINDINFOA *'
There is no context in which this conversion is possible
CListView.cpp(109) : error C2597: illegal reference to data member 'CListView::hWndListView' in a static member function
CListView.cpp(111) : warning C4551: function call missing argument list
CListView.cpp(111) : error C2597: illegal reference to data member 'CListView::bSortAscend' in a static member function
main.cpp
Error executing cl.exe.
ListView.exe - 10 error(s), 1 warning(s)
Code:
// CListView.cpp
#include "CListView.h"
CListView::CListView()
{
initCommCtls.dwICC = ICC_LISTVIEW_CLASSES;
initCommCtls.dwSize = sizeof(INITCOMMONCONTROLSEX);
InitCommonControlsEx(&initCommCtls);
lvColumn.mask = LVCF_TEXT | LVCF_WIDTH;
lvItem.mask = LVIF_TEXT | LVIF_PARAM;
lvItem.iSubItem = 0;
nColumns = 0;
bSortAscend = false;
}
void CListView::SetHwnd(HWND& hWnd, int nIDDlgItem)
{
hWndListView = GetDlgItem(hWnd, nIDDlgItem);
}
void CListView::SetColumns(int nCount, int nSize[], char* szText[])
{
nColumns = nCount;
for(int i = 0; i < nCount; i++)
{
lvColumn.cx = nSize[i];
lvColumn.pszText = szText[i];
ListView_InsertColumn(hWndListView, i, &lvColumn);
}
}
void CListView::InsertRow(char* szText[])
{
int nCount = ListView_GetItemCount(hWndListView);
lvItem.iItem = lvItem.lParam = nCount;
lvItem.pszText = szText[0];
ListView_InsertItem(hWndListView, &lvItem);
for(int i = 1; i < nColumns; i++)
{
ListView_SetItemText(hWndListView, nCount, i, szText[i]);
}
}
void CListView::SortItems(LPARAM lParam)
{
nmListView = (LPNMLISTVIEW)lParam;
if(nmListView->hdr.code == LVN_COLUMNCLICK)
{
if(nLastCol != nmListView->iSubItem)
{
bSortAscend = false;
}
ListView_SortItems(nmListView->hdr.hwndFrom,
/*problems here ------>*/(PFNLVCOMPARE)CompareString, nmListView->iSubItem);
if(bSortAscend)
{
bSortAscend = false;
}
else
{
bSortAscend = true;
}
}
}
static INT CALLBACK CListView::CompareString(LPARAM lParam1, LPARAM lParam2,
LPARAM lParamSort)
{
char szText1[32];
char szText2[32];
int iIndex;
lvFindInfo.lParam = lParam1;
iIndex = ListView_FindItem(hWndListView, -1, &lvFindInfo);
ListView_GetItemText(hWndListView, iIndex, (INT)lParamSort, (LPTSTR)szText1, 16);
lvFindInfo.lParam = lParam2;
iIndex = ListView_FindItem(hWndListView, -1, &lvFindInfo);
ListView_GetItemText(hWndListView, iIndex, (INT)lParamSort, (LPTSTR)szText2, 16);
if(bSortAscend)
{
return -strcmp(szText1, szText2);
}
else
{
return strcmp(szText1, szText2);
}
return 0;
}
I don't want to take the function out of the class because I'd prefer everything to stay together. There should be a way.
Last edited by wey97; Dec 21st, 2002 at 07:50 PM .
Dec 22nd, 2002, 10:39 AM
#6
No there isn't.
Let's see...
Don't use the cast. It shouldn't be necessary. If the compiler produces an error without the cast then you've done something wrong.
The function must be static. There's no way around that. But it doesn't have to be a complicated function. When using classes you usually only add a stub:
Code:
class CListView
{
//...
INT CALLBACK CompareString(LPARAM lParam1, LPARAM lParam2);
static INT CALLBACK CompareStringStub(LPARAM lParam1, LPARAM lParam2, LPARAM, lParamUser);
// ...
};
// In SortItems:
ListView_SortItems(nmListView->hdr.hwndFrom,
CompareStringStub, (LPARAM)this);
// The CompareStringStub function:
INT CALLBACK CListView::CompareStringStub(LPARAM lP1, LPARAM lP2, LPARAM lPUser)
{
return ((CListView *)lPUser)->CompareString(lP1, lP2);
}
All the buzzt
CornedBee
"Writing specifications is like writing a novel. Writing code is like writing poetry."
- Anonymous, published by Raymond Chen
Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.
Dec 23rd, 2002, 10:29 AM
#7
Thread Starter
Frenzied Member
Don't forget CompareString takes 3 parameters instead of 2.
This compiles but doesn't sort the items properly:
Code:
// CListView.h
#ifndef __CLISTVIEW_H__
#define __CLISTVIEW_H__
#include <windows.h>
#include <commctrl.h>
class CListView
{
protected:
bool bSortAscend;
int nColumns;
int nLastCol;
LVCOLUMN lvColumn;
LVITEM lvItem;
LVITEM lvFindItem;
LVFINDINFO lvFindInfo;
NMLISTVIEW *nmListView;
HWND hWndListView;
INITCOMMONCONTROLSEX initCommCtls;
public:
CListView();
void SetHwnd(HWND& hWnd, int nIDDlgItem);
void SetColumns(int nCount, int nSize[], char* szText[]);
void InsertRow(char* szText[]);
void SortItems(LPARAM lParam);
INT CALLBACK CompareString(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort);
static INT CALLBACK CompareStringStub(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort);
};
#endif // __CLISTVIEW_H__
Code:
// CListView.cpp
#include "CListView.h"
CListView::CListView()
{
initCommCtls.dwICC = ICC_LISTVIEW_CLASSES;
initCommCtls.dwSize = sizeof(INITCOMMONCONTROLSEX);
InitCommonControlsEx(&initCommCtls);
lvColumn.mask = LVCF_TEXT | LVCF_WIDTH;
lvItem.mask = LVIF_TEXT | LVIF_PARAM;
lvItem.iSubItem = 0;
nColumns = 0;
nLastCol = -1;
bSortAscend = false;
}
void CListView::SetHwnd(HWND& hWnd, int nIDDlgItem)
{
hWndListView = GetDlgItem(hWnd, nIDDlgItem);
}
void CListView::SetColumns(int nCount, int nSize[], char* szText[])
{
nColumns = nCount;
for(int i = 0; i < nCount; i++)
{
lvColumn.cx = nSize[i];
lvColumn.pszText = szText[i];
ListView_InsertColumn(hWndListView, i, &lvColumn);
}
}
void CListView::InsertRow(char* szText[])
{
int nCount = ListView_GetItemCount(hWndListView);
lvItem.iItem = lvItem.lParam = nCount;
lvItem.pszText = szText[0];
ListView_InsertItem(hWndListView, &lvItem);
for(int i = 1; i < nColumns; i++)
{
ListView_SetItemText(hWndListView, nCount, i, szText[i]);
}
}
void CListView::SortItems(LPARAM lParam)
{
nmListView = (LPNMLISTVIEW)lParam;
if(nmListView->hdr.code == LVN_COLUMNCLICK)
{
if(nLastCol != nmListView->iSubItem)
{
bSortAscend = false;
}
ListView_SortItems(nmListView->hdr.hwndFrom, CompareStringStub, (LPARAM)this);
if(bSortAscend)
{
bSortAscend = false;
}
else
{
bSortAscend = true;
}
nLastCol = nmListView->iSubItem;
}
}
INT CALLBACK CListView::CompareString(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
{
char szText1[32];
char szText2[32];
int iIndex;
lvFindInfo.lParam = lParam1;
iIndex = ListView_FindItem(hWndListView, -1, &lvFindInfo);
ListView_GetItemText(hWndListView, iIndex, lParamSort, (LPTSTR)szText1, 16);
lvFindInfo.lParam = lParam2;
iIndex = ListView_FindItem(hWndListView, -1, &lvFindInfo);
ListView_GetItemText(hWndListView, iIndex, lParamSort, (LPTSTR)szText2, 16);
if(bSortAscend)
{
return -strcmp(szText1, szText2);
}
else
{
return strcmp(szText1, szText2);
}
return 0;
}
INT CALLBACK CListView::CompareStringStub(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
{
return ((CListView*)lParamSort)->CompareString(lParam1, lParam2, lParamSort);
}
Code:
// main.cpp
#include "CListView.h"
#include "resource.h"
CListView cList;
BOOL CALLBACK DialogProc(HWND hWnd, UINT uMsg,
WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_INITDIALOG:
{
cList.SetHwnd(hWnd, IDC_LIST1);
char* szText[3] = {"Column 1", "Column 2", "Column 3"};
int nSize[3] = {100, 75, 75};
cList.SetColumns(3, nSize, szText);
szText[0] = "aaaaxkkjlj";
szText[1] = "04/24/2002";
szText[2] = "99";
cList.InsertRow(szText);
szText[0] = "edkkljkjk";
szText[1] = "10/18/2002";
szText[2] = "11";
cList.InsertRow(szText);
szText[0] = "kjdkdjdkdj";
szText[1] = "07/29/1977";
szText[2] = "22";
cList.InsertRow(szText);
ShowWindow(hWnd, SW_SHOW);
break;
}
case WM_CLOSE:
{
PostQuitMessage(0);
break;
}
case WM_NOTIFY:
{
cList.SortItems(lParam);
break;
}
default:
{
return FALSE;
}
}
return FALSE;
}
INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpszArgument, INT iCmdShow)
{
MSG msg;
HWND hWndDialog;
hWndDialog = CreateDialog(hInstance, (LPCTSTR)IDD_DIALOG1, NULL, (DLGPROC)DialogProc);
while(GetMessage(&msg, NULL, 0, 0))
{
if(!IsDialogMessage(hWndDialog, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return msg.wParam;
}
Attached Files
Dec 23rd, 2002, 10:58 AM
#8
I've intentionally left out the third parameter for CompareStrings, it has no meaning. The third parameter to CompareStringsStub is the this pointer, which is availbable to CompareStrings anyway. You'll have to pass what you originally intended for the third parameter by some other means (class member?).
All the buzzt
CornedBee
"Writing specifications is like writing a novel. Writing code is like writing poetry."
- Anonymous, published by Raymond Chen
Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.
Posting Permissions
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
Forum Rules
Click Here to Expand Forum to Full Width