CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 10 of 10
  1. #1
    Join Date
    Nov 2005
    Posts
    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

  2. #2
    Join Date
    May 1999
    Location
    ALABAMA, USA
    Posts
    9,917

    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.

  3. #3
    Join Date
    Nov 2008
    Posts
    13

    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

  4. #4
    Join Date
    Nov 2008
    Posts
    34

    Re: Comment retrieve msg from CListCtrl dynamicaly created?

    Quote Originally Posted by qadddd View Post
    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

  5. #5
    Join Date
    May 1999
    Location
    ALABAMA, USA
    Posts
    9,917

    Re: Comment retrieve msg from CListCtrl dynamicaly created?

    Quote Originally Posted by skypin View Post
    try use SetWindowLong or SetClassLong

    Are you sure this is the right post?
    There are only 10 types of people in the world:
    Those who understand binary and those who do not.

  6. #6
    Join Date
    Nov 2008
    Posts
    34

    Re: Comment retrieve msg from CListCtrl dynamicaly created?

    Quote Originally Posted by JohnCz View Post

    Are you sure this is the right post?
    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.

  7. #7
    Join Date
    Nov 2008
    Posts
    34

    Re: Comment retrieve msg from CListCtrl dynamicaly created?

    Quote Originally Posted by qadddd View Post
    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

  8. #8
    GCDEF is offline Elite Member Power Poster
    Join Date
    Nov 2003
    Location
    Florida
    Posts
    12,637

    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

  9. #9
    Join Date
    Nov 2008
    Posts
    34

    Re: Comment retrieve msg from CListCtrl dynamicaly created?

    Quote Originally Posted by GCDEF View Post
    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 .

  10. #10
    Join Date
    May 1999
    Location
    ALABAMA, USA
    Posts
    9,917

    Re: Comment retrieve msg from CListCtrl dynamicaly created?

    Quote Originally Posted by skypin View Post
    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
  •  





Click Here to Expand Forum to Full Width

Featured