1. We have moved from vBulletin to XenForo and you are viewing the site in the middle of the move. Though the functional aspect of everything is working fine, we are still working on other changes including the new design on Xenforo.
    Dismiss Notice

Hook windows control messages through subclassing

Discussion in 'Win32' started by d_arin100, Oct 13, 2009.

  1. d_arin100

    d_arin100 New Member

    Joined:
    Sep 25, 2009
    Messages:
    10
    Likes Received:
    3
    Trophy Points:
    0
    Location:
    Bangalore
    Subclassing is a very powerful tool in creating your own custom controls and modifying the standard windows interface. This is typically done by replacing the Window Procedure for a window with application-defined window procedure. Subclassing is a technique that allows an application to intercept messages destined for another window. This article contains subclassing in SDK as well as subclassing in MFC programs.

    SDK subclassing



    Sometimes we need to modify the functionality of control and customize it slightly depending on the application. Let we need a letter only edit control (A control which take only letter no numeric & other special character.). Here subclassing is a rescuer for resolving it. Subclassing involves replacing the Message Handlers of the control, and passing any unprocessed message to the controls Message Handler. By using SetWindowLong() we can specify a new Window Procedure for the control which needs to be subclass.

    Code:
    WNDPROC g_pOldProc;
    BOOL CALLBACK MyDialogProc(HWND, UINT, WPARAM, LPARAM);
    LRESULT CALLBACK MyEditProc(HWND, UINT, WPARAM, LPARAM);
    int WINAPI WinMain(HINSTANCE hInstance,   HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
    {
        DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, MyDialogProc, 0);
        return TRUE;
    }
     
    BOOL CALLBACK MyDialogProc(HWND hWndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
    {     
          HWND hMyEdit;
          switch (uMsg) 
          { 
             case WM_INITDIALOG: 
                   hMyEdit = GetDlgItem(hWndDlg, IDC_EDIT);
                   /// Subclass the Edit control
                   g_pOldProc = (WNDPROC)SetWindowLong(hMyEdit, GWL_WNDPROC, (LONG)MyEditProc);
                   return TRUE; 
             case WM_COMMAND:
                     switch(LOWORD(wParam))
                       {
                          case IDOK:
                                    EndDialog(hWndDlg, LOWORD(wParam));
                       }
                     return TRUE;
          }
          return FALSE;
    } 
     
    LRESULT CALLBACK MyEditProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
          TCHAR chChar;
          switch (message)
          {
              case WM_CHAR:
                        chChar = (TCHAR) wParam;
                        /// Is the char is an alphabetic character
                            if(!IsCharAlpha(chChar))
                                  return 0;
                            break;
          }
          return CallWindowProc (g_pOldProc, hwnd, message, wParam, lParam);
    }
    
    Now any message to the edit control will first go through the "MyEditProc" Window Procedure, which will decide whether the message will go or not to the edit control's Window Procedure.

    MFC Subclassing



    Subclassing in a MFC program is similar to SDK subclassing. MFC Subclassing also done by replacing the message handlers of a control. First we need to inherit the class from a control class.
    Code:
    class CLetterEdit : public CEdit
    {
     
       public:
             CLetterEdit();
     
       public:
             virtual ~CLetterEdit();
     
       protected:
          //{{AFX_MSG(CLetterEdit)
          afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);
          //}}AFX_MSG
     
          DECLARE_MESSAGE_MAP()
    }; 
    
    Then we need to add Message Handlers of the new class.
    Code:
    void CLetterEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) 
    {
          if(IsCharAlpha((TCHAR)nChar))
                /// The control's message handler has been called
                CEdit::OnChar(nChar, nRepCnt, nFlags);
    }
    
    Next we need to associate the window with an instance of our new class.
    Code:
    CLetterEdit m_edit;
     
    DDX_Control(pDX, IDC_EDIT, m_edit);
    
     
    shabbir likes this.
  2. chyssa

    chyssa New Member

    Joined:
    Oct 23, 2009
    Messages:
    2
    Likes Received:
    0
    Trophy Points:
    0
    Thanks for sharing your codes...
     
  3. shabbir

    shabbir Administrator Staff Member

    Joined:
    Jul 12, 2004
    Messages:
    15,276
    Likes Received:
    364
    Trophy Points:
    83

Share This Page