Thread: Subclassing an edit box

  1. #1
    Registered User
    Join Date
    May 2012
    Posts
    3

    Exclamation Subclassing an edit box

    Hi,
    After many hours of searching, i finally found the code for a simple temperature converter.
    I'm hoping that someone can help.
    Have spent many weeks trying to nut this one out, but keep hitting dead ends
    Please don't tell me that "google is my friend" - i have looked at a truckload of websites on google relating to subclassing an editbox and none offer a simple clear-cut code example, and all the explanations that i have read leave a lot to be desired.
    I have two questions concerning the code in the code window below my questions:
    1. What is the purpose of this code: if (lParam && LOWORD (wParam) == TXTBOX2).
    2. How can i subclass TXTBOX1, so that when i hit enter on the keyboard it performs the same action as clicking on the Convert button? (can someone please insert the subclassing code into the existing code and post in in the reply - i'm sure that it would be easy for some, and would be appreciated immensely)
    I get the basic idea of subclassing an editbox with it's own subclassed proc and then using a Case statement with something like: case WM_KEYDOWN and if ((wParam == VK_RETURN), but have never come across a nice simple example like this that i might have a chance of understanding.
    If anyone can help with this, thanks.
    I think it could be of help to others also, if we can find a solution.
    Code:
    #include <windows.h>
      
      #define BUTTON 100
      #define LABEL1 101
      #define LABEL2 102
      #define TXTBOX1 501
      #define TXTBOX2 502
    #define MAXIN 10
      #define MAXOUT 25
    //FUNCTION PROTOTYPES
    LRESULT CALLBACK WndProc(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam);
    HWND SetUpWindow(char* cClass, char* cTitle, int nWidth, int nHeight, HINSTANCE   hInstance);
    //GLOBAL PARAMETERS
    HWND hWndMe, hlb1, hlb2, htb1, htb2, hBtn;
    char cBuf[MAXOUT]; // char buffer
    //SET FONT
    inline void SetDefaultFont(int identifier, HWND hwnd)
      {
      SendDlgItemMessage (hwnd, identifier, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT),   MAKELPARAM(true, 0));
      }
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdline,   int iCmdShow)
      {
      char* cClass = "Convert"; // Name of class
      char* cTitle = "Convert"; // Text in window title bar
      const int nWidth = 275; // Width of window
      const int nHeight = 100; // Height of window
     MSG msg;
     // CREATE WINDOWS
      hWndMe = SetUpWindow(cClass, cTitle, nWidth, nHeight, hInstance);
      hlb1 = CreateWindow("STATIC", "Enter temparature in Fahrenheit   :", WS_CHILD | WS_VISIBLE | SS_LEFT, 0, 5, 160, 16, hWndMe, (HMENU)LABEL1,   hInstance, NULL);
      hlb1 = CreateWindow("STATIC", "The temparature in Celcius :",   WS_CHILD | WS_VISIBLE | SS_LEFT, 0, 28, 132, 16, hWndMe, (HMENU)LABEL2, hInstance,   NULL);
      htb1 = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "", WS_CHILD   | WS_VISIBLE | ES_RIGHT , 185, 3, 80, 20, hWndMe, (HMENU)TXTBOX1, hInstance,   NULL);
      htb2 = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "", WS_CHILD   | WS_VISIBLE | ES_RIGHT , 132, 25, 133, 20, hWndMe, (HMENU)TXTBOX2, hInstance,   NULL);
      hBtn = CreateWindow("BUTTON", "Convert", WS_CHILD | WS_VISIBLE   | BS_DEFPUSHBUTTON, 185, 50, 50, 20, hWndMe, (HMENU)BUTTON, hInstance, NULL);
      
      ShowWindow(hWndMe,iCmdShow);
      UpdateWindow(hWndMe);
     cBuf[0] = 0;
      
      SetDefaultFont(LABEL1, hWndMe);
      SetDefaultFont(LABEL2, hWndMe);
      SetDefaultFont(TXTBOX1, hWndMe);
      SetDefaultFont(TXTBOX2, hWndMe);
      SetDefaultFont(BUTTON, hWndMe);
     SetWindowText(htb1, "0");
      //SetWindowText(htb2, "0");
     while(GetMessage(&msg, NULL, 0, 0))
      {
      TranslateMessage(&msg);
      DispatchMessage(&msg);
      }
     return msg.wParam;
      }
    
      LRESULT CALLBACK WndProc(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
      {
      switch (iMsg)
      {
      case WM_DESTROY:
      {
      PostQuitMessage(0);
      return 0;
      break;
      }
      case WM_COMMAND:
      {
      if (lParam && LOWORD (wParam) == TXTBOX2)
      {
      switch (HIWORD (wParam))
      {
      case EN_SETFOCUS:
      {
      SetFocus (hWndMe);
      break;
      }
      }
      break ;
      }
      switch(LOWORD(wParam))
      {
      {
      case BUTTON: // BUTTON clicked
      {
      GetWindowText(htb1, cBuf, MAXOUT);
      _gcvt((5*atof(cBuf)-160)/9, MAXOUT, cBuf);
      SetWindowText(htb2, cBuf);
      cBuf[0] = 0;
      }
      } 
      }
      }
      }
      return DefWindowProc(hWnd, iMsg, wParam, lParam);
      }
    
      HWND SetUpWindow(char* cClass, char* cTitle, int nWidth, int nHeight, HINSTANCE   hInstance)
      {
      WNDCLASS wClass;
      HWND hWnd;
     wClass.style = CS_HREDRAW | CS_VREDRAW;
      wClass.lpfnWndProc = WndProc; 
      wClass.cbClsExtra = 0;
      wClass.cbWndExtra = 0;
      wClass.hInstance = hInstance;
      wClass.hIcon = LoadIcon(NULL,IDI_ASTERISK);
      wClass.hCursor = LoadCursor(NULL,IDC_ARROW);
      wClass.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1) ;
      wClass.lpszMenuName = NULL;
      wClass.lpszClassName = cClass;
     RegisterClass(&wClass);
     hWnd = CreateWindow(cClass, cTitle, WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,   CW_USEDEFAULT, CW_USEDEFAULT, nWidth, nHeight, NULL, NULL, hInstance, NULL);
     return hWnd;
      }
    Last edited by gomer pyle; 05-26-2012 at 01:36 AM. Reason: html errors - learning curb

  2. #2
    Registered User
    Join Date
    Mar 2005
    Location
    Juneda
    Posts
    291
    "...i have looked at a truckload of websites on google relating to subclassing an editbox and none offer a simple clear-cut code example..."

    Not?? Have you seen the win32 reference manual on the section 'Subclassing a window'? Have you searched here in cboard? Myself was involved in a thread about subclassing an edit control on a listview to catch the enter keypress... yes the same subclass you are looking for.

    Subclassing is easy and helpful (also very funny to prog), have several steps: first create the control you want to subclass, then get its procedure and copy it to recoverable location and assign a new procedure; in that new procedure you have to check if you use some of its skills, if not then you have to redirect to the default and previously stored control procedure. A little bit of code:

    Code:
    WNDPROC previous_boring_subclassed_edit_proc;//global variable to save a copy of the default control procedure
    
    void subclass_the_edit_control(HWND h_edit) {
        previous_boring_subclassed_edit_proc = (WNDPROC)GetWindowLong(h_edit, GWL_WNDPROC);//get the default procedure
        SetWindowLong(h_edit, GWL_WNDPROC, (LONG_PTR)yeah_my_new_subclassed_edit_proc);//set your custom procedure :)
    }
    your new control procedure will look like a standard window procedure, except it will be expecting and responding to WM_KEYDOWN message for VK_RETURN key press; some code:

    Code:
    LRESULT CALLBACK yeah_my_new_subclassed_edit_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
        switch(msg) {
            case WM_KEYDOWN: {
                switch (wParam) {
                    case VK_RETURN: {
                        //simulate a button press, see below
                        return 0;//if the procedure responds the action, finish the control procedure
                    }
                    break;
                }
            }
            break;
        }
        return CallWindowProc(previous_boring_subclassed_edit_proc, hwnd, msg, wParam, lParam);
    }
    As you can see, if the program reaches the last function line is because the user haven't pressed enter, son you will have to redirect to the default procedure to go on with the default message processing (paint messages, other keydown messages, etc stuffs)

    Now you have to simulate the button press, just get the parent handler and send it a WM_COMMAND with BUTTON id as low order first message argument, the explanation is hard but the code is pretty simple:

    Code:
    HWND h_parent = (HWND)GetWindowLong(hwnd, GWL_HWNDPARENT);//get parent handler
    SendMessage(h_parent, WM_COMMAND, (WPARAM)MAKELPARAM(BUTTON, 0), 0);//simulate a control action


    "...What is the purpose of this code: if (lParam && LOWORD (wParam) == TXTBOX2)..."
    Good question, the purpose is to check if the user attempts to access the TXTBOX2 control, if you see the next code lines you'll see that the response to that is a focus jump to main window, is a way of preventing the user to enter data to the TXTBOX2 edit control. Is not necessary, just set ES_READONLY as control style when create it and delete this part of code; or since you have learned to subclass a control, you can subclass the TXTBOX2 control to reject whatever keypress message


    Hope that helps
    Niara
    Last edited by Niara; 05-26-2012 at 11:40 AM.

  3. #3
    Registered User
    Join Date
    May 2012
    Posts
    3

    Thumbs up One with high purpose

    Thanks, for the reply niara (thats a nice name)
    sorry for not getting back sooner but had a horrid morning with kidney stone sypmtoms and have being stuck in hospital.

    also, sorry for the formatting with the braces - it was a bit of a mission just to post it, as it doesn't paste how it was copied.
    but nevertheless the code still compiles ok

    yes, did look at the subclassing a window in win32 help.
    (that also took quite a long time to discover)
    but i couldn't work out saw how to integrate the additional code into the existing code
    (for example, can i copy the code that you wrote and just add it to the bottom of the existing code?)
    i know that it is asking a lot, but could you post the compete code so that i can slap it into the compiler?
    for me, this is the only way that i'm going to get it - to see the working product and then work backwards fiddling with the code
    and disecting it bit by bit.
    it will probably take me about a year, to gain some confidence and familiarity but at least it will hold my attention and enthusiasm.

    a while ago i actually started to get a handle (pun not intened) on this to a tiny degree like the basic structure of a win32 app, and went through a few tutorials such as forgers, (unfortunately none of them provided a simple example of an app with a subclassed editbox), but felt burnt out, and had to give it a rest for the sake of my own sanity.
    now i've forgotton some of what i learned.
    i'm a hermit and the few acquaintances that i have had, don't have any clue or the slightest interest about this stuff.
    nor am i near any place that offers programming courses, so have to do it the hard way of bumbling about.

    the reason i'm interested in this is that i want to be able to write a simple windows app, as opposed to many that just accept the technology, buying ipads and what have you, having no idea about how they work or and little control over them.
    it is not unusual, in other's computers that i have seen, to note that they chockablok with all sorts of irritating, programs, processes autoupdates, nags etc.

    cheers

  4. #4
    Registered User
    Join Date
    Mar 2005
    Location
    Juneda
    Posts
    291
    "...could you post the compete code so that i can slap it into the compiler?..."

    No, I can't post the complete code because it's your task to figure it out how to integrate . That's a single global variable and 2 external functions; once you have created the edit control identifyed by 'TXTBOX1' and stored its handler under 'htb1', you have to call 'subclass_the_edit_control()' function sending the edit control's handler, that's nothing related to win api programming but standard c / c++ programming, you must not have any problem with it. All three new elements are 'independant' of the code you provided, so add the global variable at the top (with your other globals), write the prototypes for the functions and copy them on the bottom, then just call 'subclass_the_edit_control()' after created the control and use its handler as function argument.

    theForger's is a good tutorial, check also the catch22.net tutorials tips and tricks, and of course see the cboard list of win32 programming links for more references

    Sorry to not provide more help
    Niara

  5. #5
    Registered User
    Join Date
    May 2012
    Posts
    3

    Smile

    thanks for the help,what you have provided is very much appreciated.i kind of get what you are saying.if i do get somewhere with the info that you have given i will repost here.(can't see it being anytime soon)might check back here from time to time.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Creating an Edit Box (Subclassing)
    By csonx_p in forum Windows Programming
    Replies: 9
    Last Post: 05-05-2008, 06:36 AM
  2. Subclassing
    By alex0751 in forum C++ Programming
    Replies: 2
    Last Post: 01-21-2008, 06:39 PM
  3. WTL Subclassing
    By Tonto in forum Windows Programming
    Replies: 1
    Last Post: 06-05-2007, 11:46 AM
  4. Subclassing
    By Mithoric in forum Windows Programming
    Replies: 5
    Last Post: 11-22-2003, 05:30 PM
  5. Subclassing edit control - slight problem
    By Shag in forum Windows Programming
    Replies: 3
    Last Post: 11-03-2002, 12:33 AM