|
-
December 14th, 2008, 10:56 AM
#1
Comment retrieve msg from CListCtrl dynamicaly created?
Hello,
I have a dialog containing a CListCtrl, je retrieve the performed actions (click, right click,etc) on this list thanks to ON_NOTIFY(NM_CLICK, IDC_LIST2, <RoutineName>) in //{{AFX_MSG_MAP(CTestList).
It works well in this case.
Now, my dialog is empty and I build dynamicaly the CListCtrl with:
m_Liste = new CListCtrl;
VERIFY (m_Liste->Create (WS_VISIBLE | WS_CHILD | LVS_REPORT | LVS_EDITLABELS, CRect (10, 10, 300, 300), this, IDI_LIST));
If I have a ON_NOTIFY(NM_CLICK, IDI_LIST, <RoutineName>) I got 2 compil errors on line ON_NOTIFY :
- error C2065: '<RoutineName>' : undeclared identifier
- error C2440: 'type cast' : cannot convert from 'int *' to 'void (__thiscall CCmdTarget::*)(struct tagNMHDR *,long *)'
What do I have to do to retrieve the performed actions and execute the right routine depending on msg type??
Thanks in advance
DD
-
December 14th, 2008, 11:54 AM
#2
Re: Comment retrieve msg from CListCtrl dynamicaly created?
First of all. You are allocating CListCtrl object on the heap. This is unnecessary and requires you to remember to free memory allocated by calling delete. Use class’ member variable instead.
Set of errors tells you that you do not have RoutineName declared. I hope that RoutineName is a name of the handler.
Why you create list control at the run time?
There are only 10 types of people in the world:
Those who understand binary and those who do not.
-
December 14th, 2008, 01:28 PM
#3
Re: Comment retrieve msg from CListCtrl dynamicaly created?
Hello,
Now, my dialog is empty and I build dynamicaly the CListCtrl with:
Does it mean your dialog dont have IDC_LIST2 ?
Regards,
John,
http://www.simpletools.co.in
-
December 14th, 2008, 03:53 PM
#4
Re: Comment retrieve msg from CListCtrl dynamicaly created?
 Originally Posted by qadddd
Hello,
I have a dialog containing a CListCtrl, je retrieve the performed actions (click, right click,etc) on this list ..
try use SetWindowLong or SetClassLong
Code:
m_Liste = new CListCtrl;
SetWindowLong (m_Liste->m_hWnd , GWL_WNDPROC , (LONG)MyListProc);
Or :
Code:
m_Liste = new CListCtrl;
SetClassLong (m_Liste->m_hWnd ,GCL_WNDPROC, (LONG)MySubClassListProc)
Last edited by skypin; December 14th, 2008 at 11:07 PM.
Reason: correct something wrong
-
December 14th, 2008, 04:51 PM
#5
Re: Comment retrieve msg from CListCtrl dynamicaly created?
There are only 10 types of people in the world:
Those who understand binary and those who do not.
-
December 14th, 2008, 11:44 PM
#6
Re: Comment retrieve msg from CListCtrl dynamicaly created?
 Originally Posted by JohnCz
Please see this SetWindowLong
Also see this SetClassLong
And these both in Subclassing under : [WARNING: An application should not attempt to subclass or superclass a window that belongs to another process.]
this code given from above site (SetClassLong.)
Code:
// Anyway, here is code that works:
#include <windows.h>
WNDPROC DefEditProc = NULL;
LRESULT CALLBACK MyEditProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
char* ClassName = "mywindowclass";
HWND hMain = NULL;
HWND hChild1 = NULL;
HWND hChild2= NULL;
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
break;
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wc;
MSG Msg;
//create and register window class
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)COLOR_BACKGROUND;
wc.lpszMenuName = NULL;
wc.lpszClassName = ClassName;
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
RegisterClassEx(&wc);
//create main window
hMain = CreateWindowEx(
WS_EX_CONTROLPARENT, //extended style
ClassName, //window class
"The Main Window", //name
WS_OVERLAPPEDWINDOW, //style
CW_USEDEFAULT, CW_USEDEFAULT, 300, 300,
NULL, //parent window
NULL, //menu
hInstance, //program instance
NULL
);
ShowWindow(hMain, nCmdShow);
UpdateWindow(hMain);
//CHILD WINDOWS
hChild1=CreateWindowEx(WS_EX_CLIENTEDGE,"EDIT","",
WS_VISIBLE|WS_CHILD|WS_TABSTOP,
10,10,40,20,hMain,(HMENU)7001,hInstance,NULL);
hChild2=CreateWindowEx(WS_EX_CLIENTEDGE,"EDIT","",
WS_VISIBLE|WS_CHILD|WS_TABSTOP,
60,10,40,20,hMain,(HMENU)7002,hInstance,NULL);
//END OF CHILD WINDOWS
DefEditProc = (WNDPROC)SetWindowLong(hChild1,GWL_WNDPROC,(LONG)MyEditProc);
SetWindowLong(hChild2,GWL_WNDPROC,(LONG)MyEditProc);
while(GetMessage(&Msg, NULL, 0, 0) > 0)
{
if ((Msg.message == WM_KEYDOWN && Msg.wParam == VK_RETURN) || !IsDialogMessage(hMain,&Msg))
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
}
return Msg.wParam;
}
LRESULT CALLBACK MyEditProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_KEYDOWN:
{
if (wParam == VK_RETURN)
/* Do stuff */
else
return CallWindowProc(DefEditProc,hwnd,msg,wParam,lParam);
} break;
default:
return CallWindowProc(DefEditProc,hwnd,msg,wParam,lParam);
}
}
//The problem was that I was telling you to use SetClassLong, whereas you really had to use SetWindowLong.
Last edited by skypin; December 15th, 2008 at 11:31 AM.
-
December 17th, 2008, 04:10 PM
#7
Re: Comment retrieve msg from CListCtrl dynamicaly created?
 Originally Posted by qadddd
Hello,
I have a dialog containing a CListCtrl, je retrieve the performed actions (click, right click,etc) on this list thanks to ON_NOTIFY(NM_CLICK, IDC_LIST2 ...
If you want get notify of mouse only you can use SetWindowsHookEx on mouse to get all notifications of mouse events ...
I write hole a code for you , so you need first create new based Dialog application and named
CTest then do :
copy this code to the header file :
Code:
#define IDC_LISTCRL 4000
#define LVIS_MOUSEMOVE (WM_USER + 21)
#define LVIS_MOUSEWHEEL (WM_USER + 22)
#define LVIS_LBUTTONDOWN (WM_USER + 23)
#define LVIS_RBUTTONDOWN (WM_USER + 24)
#define LVIS_MBUTTONDOWN (WM_USER + 25)
#define LVIS_LBUTTONDBLCLK (WM_USER + 26)
#define LVIS_RBUTTONDBLCLK (WM_USER + 27)
#define LVIS_MBUTTONDBLCLK (WM_USER + 28)
#define LVIS_LBUTTONUP (WM_USER + 29)
#define LVIS_RBUTTONUP (WM_USER + 30)
#define LVIS_MBUTTONUP (WM_USER + 31)
then add these code under CCTestDlg construction:
Code:
class CCTestDlg : public CDialog
{
// Construction
public:
//..
HHOOK m_hHook;
bool UnInstallMouseHook ();
bool InstallMouseHook ();
private:
CListCtrl * m_Liste;
//..
and add WindowProc virtual functions under DoDataExchange
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CCTestDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam); // add this
Finally go to your implementations file and add these codes:
Code:
LRESULT CCTestDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
// TODO: Add your specialized code here and/or call the base class
if(message == WM_INITDIALOG)
{
m_hHook = false;
m_Liste = new CListCtrl;
VERIFY (m_Liste->Create (WS_VISIBLE | WS_CHILD | LVS_REPORT | LVS_EDITLABELS, CRect (10, 10, 300, 300), this, IDC_LISTCRL));
InstallMouseHook();
for (int i =0; i< 30; i++)
m_Liste->InsertItem (i,"ss",0);
}
if(WM_DESTROY == message)
{
delete m_Liste;
UnInstallMouseHook();
}
// Notifications of ListCtrl.
if(message == WM_MOUSEWHEEL)
{
CPoint point = CPoint(LOWORD(lParam),HIWORD(lParam) );
if(::WindowFromPoint (point) == m_Liste->m_hWnd){
::ScreenToClient (m_Liste->m_hWnd, &point);
PostMessage(LVIS_MOUSEWHEEL,wParam,MAKELPARAM(point.x,point.y));
}
}
switch ( message )
{
default:
break;
// mouse move notification
case LVIS_MOUSEMOVE:
TRACE2("\nOnList_MouseMove [y:%d/y:%d]\n", LOWORD(lParam), HIWORD(lParam));
break;
// mouse wheel move notification
case LVIS_MOUSEWHEEL:
TRACE2("\nOnList_Scroll [y:%d/y:%d]\n", LOWORD(lParam), HIWORD(lParam));
break;
// mouse button down notifications
case LVIS_LBUTTONDOWN:
TRACE2("\nOnList_MouseLeftDown [y:%d/y:%d]\n", LOWORD(lParam), HIWORD(lParam));
break;
case LVIS_RBUTTONDOWN:
TRACE2("\nOnList_MouseRightDown [y:%d/y:%d]\n", LOWORD(lParam), HIWORD(lParam));
break;
case LVIS_MBUTTONDOWN:
TRACE2("\nOnList_MouseMiddleDown [y:%d/y:%d]\n", LOWORD(lParam), HIWORD(lParam));
break;
// mouse double click notifications
case LVIS_LBUTTONDBLCLK:
TRACE2("\nOnList_MouseLeftDoubeClick [y:%d/y:%d]\n", LOWORD(lParam), HIWORD(lParam));
break;
case LVIS_RBUTTONDBLCLK:
TRACE2("\nOnList_MouseRightDoubleCLick [y:%d/y:%d]\n", LOWORD(lParam), HIWORD(lParam));
break;
case LVIS_MBUTTONDBLCLK:
TRACE2("\nOnList_MouseMiddleDoubleCick [y:%d/y:%d]\n", LOWORD(lParam), HIWORD(lParam));
break;
// mouse button up notifications
case LVIS_LBUTTONUP:
TRACE2("\nOnList_LeftButtonUp [y:%d/y:%d]\n", LOWORD(lParam), HIWORD(lParam));
break;
case LVIS_RBUTTONUP:
TRACE2("\nOnList_RightButtonUp [y:%d/y:%d]\n", LOWORD(lParam), HIWORD(lParam));
break;
case LVIS_MBUTTONUP:
TRACE2("\nOnList_MiddleButtonUp [y:%d/y:%d]\n", LOWORD(lParam), HIWORD(lParam));
break;
}
return CDialog::WindowProc(message, wParam, lParam);
}
//mouse hook callback function
LRESULT CALLBACK MouseHook(int iCode, WPARAM wParam, LPARAM lParam)
{
PMOUSEHOOKSTRUCT mh;
if (iCode == HC_ACTION) {
mh=(PMOUSEHOOKSTRUCT)lParam;
// hook only on ListCrl.
if( ::GetDlgCtrlID(mh->hwnd)!= IDC_LISTCRL )
goto ExitHook;
// convert points from screen coordinate to Client(ListCtrl).
ScreenToClient(mh->hwnd,&mh->pt);
if(wParam == WM_MOUSEMOVE) // if you need mouse move points
AfxGetMainWnd()->PostMessage(LVIS_MOUSEMOVE ,0, MAKELPARAM(mh->pt.x,mh->pt.y));
if(wParam == WM_LBUTTONDOWN)
AfxGetMainWnd()->PostMessage(LVIS_LBUTTONDOWN ,0 , MAKELPARAM(mh->pt.x,mh->pt.y));
if(wParam == WM_LBUTTONDBLCLK)
AfxGetMainWnd()->PostMessage(LVIS_LBUTTONDBLCLK ,0 , MAKELPARAM(mh->pt.x,mh->pt.y));
if(wParam == WM_RBUTTONDOWN)
AfxGetMainWnd()->PostMessage(LVIS_RBUTTONDOWN ,0 , MAKELPARAM(mh->pt.x,mh->pt.y));
if(wParam == WM_RBUTTONDBLCLK)
AfxGetMainWnd()->PostMessage(LVIS_RBUTTONDBLCLK ,0 , MAKELPARAM(mh->pt.x,mh->pt.y));
if(wParam == WM_MBUTTONDOWN)
AfxGetMainWnd()->PostMessage(LVIS_MBUTTONDOWN ,0 , MAKELPARAM(mh->pt.x,mh->pt.y));
if(wParam == WM_MBUTTONDBLCLK)
AfxGetMainWnd()->PostMessage(LVIS_MBUTTONDBLCLK ,0 , MAKELPARAM(mh->pt.x,mh->pt.y));
if(wParam == WM_LBUTTONUP)
AfxGetMainWnd()->PostMessage(LVIS_LBUTTONUP ,0, MAKELPARAM(mh->pt.x,mh->pt.y));
if(wParam == WM_RBUTTONUP)
AfxGetMainWnd()->PostMessage(LVIS_RBUTTONUP ,0, MAKELPARAM(mh->pt.x,mh->pt.y));
if(wParam == WM_MBUTTONUP)
AfxGetMainWnd()->PostMessage(LVIS_MBUTTONUP ,0, MAKELPARAM(mh->pt.x,mh->pt.y));
}
ExitHook:
return CallNextHookEx(NULL,iCode,wParam,lParam);
}
//start mouse hook
bool CCTestDlg::InstallMouseHook()
{
// if(m_hHook) return false;
m_hHook = SetWindowsHookEx(WH_MOUSE ,(HOOKPROC)MouseHook, 0, GetCurrentThreadId());
if (!m_hHook) return false;
return true;
}
//stops mouse hook
bool CCTestDlg::UnInstallMouseHook()
{
if(m_hHook) UnhookWindowsHookEx(m_hHook);
else return false;
return true;
}
Now you can get notify of mouse events on your dynamic list :
- Mouse move
- Mouse Left click
- Mouse right click
- Mouse middle click
- Mouse double left click
- Mouse double right click
- Mouse double middle click
- Mouse Wheel (moving - scrolling)
all these events have points of current screen (your list )
Hope this Help
-
December 17th, 2008, 04:13 PM
#8
Re: Comment retrieve msg from CListCtrl dynamicaly created?
skypin, none of that is necessary with the message map in place. Did you read the compiler error and the actual problem?
- error C2065: '<RoutineName>' : undeclared identifier
Pointed out by JohnCz in the first reply
-
December 17th, 2008, 04:33 PM
#9
Re: Comment retrieve msg from CListCtrl dynamicaly created?
 Originally Posted by GCDEF
skypin, none of that is necessary with the message map in place. Did you read the compiler error and the actual problem?
- error C2065: '<RoutineName>' : undeclared identifier
Pointed out by JohnCz in the first reply
first thanks to JohnCz for helps.
Yes I know , but the problem can solve it by many way .. so this can helps by any control added dynamically .
-
December 21st, 2008, 10:06 AM
#10
Re: Comment retrieve msg from CListCtrl dynamicaly created?
 Originally Posted by skypin
Yes I know , but the problem can solve it by many way .. so this can helps by any control added dynamically .
Yes, it would be the best for Win32 application.
In MFC based application, all controls are already subclassed by the framework. That is why C++ wrapper class object can represent each control.
The simplest way therefore, is to map messages using proper MFC message mapping (already in place) using minimal amount of code. Less code you have to write, less error-prone it is (in accordance with my MEMC postulate).
There are only 10 types of people in the world:
Those who understand binary and those who do not.
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
|