Menu

Subclassing Edit Control

2007-03-07
2012-09-26
  • Frederick J. Harris

    When using SetWindowLong() to subclass an edit control, I have found various documentation
    that states the address of the original window procedure should be reset at application
    close out during the WM_CLOSE or WM_DESTROY message. On the other hand, I learned Sdk style
    Windows programming mostly from Charles Petzold's books, and in his only examples of
    subclassing in his Colors program he does not do this. This is true in his Windows 95 book
    and in his Windows 98 book. So I've never done it either the many times I've done this, and
    to the best of my knowledge with no ill effects.

    Kyle Marsh from Microsoft states this in his article "Safe Subclassing In Win32"

    The application also needs the original window procedure address for removing the subclass from the window. The application removes the subclass from the window by calling SetWindowLong again. The application passes the address of the original window procedure with the GWL_WNDPROC option and the handle to the window being subclassed.

    Can anyone shed some light on this for me? Petzold couldn't possibly be wrong could he?

     
    • Nobody/Anonymous

      IMHO that's right. AFAIK that is the canonical (and now disappearing) form to do the thing. More or les exactly what I do. The only difference is that I omit the

      SetWindowLong (GetDlgItem(hwnd,IDC_TEXTBOX), GWL_WNDPROC, (DWORD)fnOldEdit);

      sentence int the VM_CLOSE case clause.

      Old Newbie.

       
    • Nobody/Anonymous

      AFAIK there are not necessity to restore the original window proc when you close the application. I never do that without known "ill effects".

      I never had read that necessity in other books.

      Old Newbie.

       
    • Frederick J. Harris

      Thanks for the reply Old Newbie. If I understand you right you see it pretty much the way I do. Below is a specific example using Sdk style. All I did was create a simple window, add a text box to the middle of it, then use SetWindowLong() in the WM_CREATE message to subclass it like so...

      fnOldEdit=(WNDPROC)SetWindowLong(hTextBox,GWL_WNDPROC,(LONG)EditProc);

      then in the WM_CLOSE message...

      SetWindowLong(GetDlgItem(hwnd,IDC_TEXTBOX),GWL_WNDPROC,(DWORD)fnOldEdit);

      Below is the full program, but I really see no need to do this at all???
      (shure wish code would format here)
      //

      include <windows.h>

      define IDC_TEXTBOX 1200

      WNDPROC fnOldEdit;
      //
      LRESULT CALLBACK EditProc(HWND hwnd,UINT iMsg,WPARAM wParam,LPARAM lParam)
      {
      return CallWindowProc(fnOldEdit, hwnd, iMsg, wParam, lParam);
      }
      //
      LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
      {
      HINSTANCE hIns;
      HWND hTextBox;
      int iStyle;

      switch (message)
      {
      case WM_CREATE:
      hIns=((LPCREATESTRUCT)lParam)->hInstance;
      iStyle=WS_CHILD | WS_VISIBLE | WS_BORDER;
      hTextBox=CreateWindow("edit",0,iStyle,90,60,50,25,hwnd,(HMENU)(IDC_TEXTBOX),hIns,0);
      fnOldEdit=(WNDPROC)SetWindowLong(hTextBox,GWL_WNDPROC,(LONG)EditProc);
      return 0;
      case WM_CLOSE:
      SetWindowLong(GetDlgItem(hwnd,IDC_TEXTBOX),GWL_WNDPROC,(DWORD)fnOldEdit);
      PostQuitMessage(0);
      return 0;
      }

      return DefWindowProc(hwnd, message, wParam, lParam);
      }

      int WINAPI WinMain(HINSTANCE hIns,HINSTANCE hPrev,LPSTR lpszArg,int iShow)
      {
      WNDCLASSEX wincl;
      MSG messages;
      HWND hWnd;

      wincl.hInstance = hIns;
      wincl.lpszClassName = "Form1";
      wincl.lpfnWndProc = WndProc;
      wincl.style = CS_HREDRAW | CS_VREDRAW;
      wincl.cbSize = sizeof(WNDCLASSEX);
      wincl.hIcon = LoadIcon(NULL, IDI_APPLICATION);
      wincl.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
      wincl.hCursor = LoadCursor(NULL, IDC_ARROW);
      wincl.lpszMenuName = NULL;
      wincl.cbClsExtra = 0;
      wincl.cbWndExtra = 0;
      wincl.hbrBackground = (HBRUSH) GetStockObject(LTGRAY_BRUSH);
      RegisterClassEx(&wincl);
      hWnd=CreateWindow("Form1","Form1",WS_OVERLAPPEDWINDOW,150,200,250,200,0,0,hIns,0);
      ShowWindow(hWnd,iShow);
      while(GetMessage(&messages,NULL,0,0))
      {
      TranslateMessage(&messages);
      DispatchMessage(&messages);
      }

      return messages.wParam;
      }

       

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.