Thread: Q's About Edit Controls

  1. #1
    Registered User Tonto's Avatar
    Join Date
    Jun 2005
    Location
    New York
    Posts
    1,465

    Q's About Edit Controls

    Hi, I have a few questions about edit controls

    1) I also have a single line edit control. I want to know when the user has hit the enter key when the edit control has focus. Can I recieve notification of this? Do I have to subclass the control? P.S. ES_WANTRETURN is not what I want, I want notification of the enter key being pressed in a single line edit control. Would subclassing help?

    2) I have a static icon control with SS_NOTIFY enabled so I get STN_CLICKED notifications when it is clicked. I want to send the control STM_SETICON messages when I recieve a click notification and change the icon (so it looks like it's been 'clicked'). Can I count that the next WM_LBUTTON up after an STN_CLICKED will be the user unclicking the static control? Can I just recieve notifications of this so I can change the static icon control to looking unclicked? Would subclassing help?

  2. #2
    {Jaxom,Imriel,Liam}'s Dad Kennedy's Avatar
    Join Date
    Aug 2006
    Location
    Alabama
    Posts
    1,065
    Quote Originally Posted by Tonto
    Hi, I have a few questions about edit controls

    1) I also have a single line edit control. I want to know when the user has hit the enter key when the edit control has focus. Can I recieve notification of this? Do I have to subclass the control? P.S. ES_WANTRETURN is not what I want, I want notification of the enter key being pressed in a single line edit control. Would subclassing help?
    I think that any message that gets sent to a child also gets sent to the parent too. . . therefore, if you know the hwnd of the child you could look at WM_KEYDOWN/WM_KEYUP with if (hwnd == MYCHILDHWND) -- which works because of the whole pointer pointing to one location in memory. . . Then you could do whatever you wanted with the information.

    Hope this helps!

  3. #3
    erstwhile
    Join Date
    Jan 2002
    Posts
    2,227
    1. Subclassing would definitely help.

    2. Seems like monitoring all mouse messages is required, in which case a WH_MOUSE hook might be an option. For less overkill, subclass the static control and SetCapture/ReleaseCapture to ensure precise control over mouse messages.
    CProgramming FAQ
    Caution: this person may be a carrier of the misinformation virus.

  4. #4
    Registered User Tonto's Avatar
    Join Date
    Jun 2005
    Location
    New York
    Posts
    1,465
    Can I make it not have that little beep tone when I hit enter?

  5. #5
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    1) The SDK docs say that pressing enter is equivalent to clicking the owning dialog's default button. So if your main window is or pretends to be a dialog, it would the corresponding notification.

    2) Wouldn't an owner-draw button be simpler?
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  6. #6
    Software Developer jverkoey's Avatar
    Join Date
    Feb 2003
    Location
    New York
    Posts
    1,905
    1) This tutorial at The Code Project should help out. (Google search for: subclass edit control WM_CHAR)

    2) I definitely agree with CornedBee, you'll have a much easier time using an owner-drawn button (Google search for: owner drawn buttons site:msdn.microsoft.com).
    --This will give you a DRAWITEMSTRUCT structure that contains all of the information you're looking for).

  7. #7
    erstwhile
    Join Date
    Jan 2002
    Posts
    2,227
    Quote Originally Posted by CornedBee
    2) Wouldn't an owner-draw button be simpler?
    I suppose this depends on what's needed, but there's not much to either approach. However, given the OP wants it "so it looks like it's been 'clicked'"(which I didn't see initially), then owner drawn does seem the more typical solution.

    Here's a quick example of both which may be of some interest:
    Code:
    /*===========================================================================*/
    /*
    Ken Fitlike 2006 - Free to good home
    
    Demonstration of owner drawn button and subclassed static control
    
    */
    /*===========================================================================*/
    #include <windows.h>
    #include <tchar.h>
    
    #define IDC_STATIC_ICON 100
    #define IDC_BUTTON      200
    /*===========================================================================*/
    LRESULT CALLBACK WndProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam);
    int OnCreate(HWND hwnd,CREATESTRUCT *cs);
    void OnDrawItem(HWND hwnd,DRAWITEMSTRUCT *ds);
    
    LRESULT CALLBACK CntrlProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam);
    
    WNDPROC oldproc;
    /*===========================================================================*/
    int WINAPI WinMain(HINSTANCE hInst,HINSTANCE hPrev,LPSTR pStr,int nCmd)
    {
    HWND       hwnd;
    MSG        msg;
    TCHAR      classname[]=_T("kenf's_wnd");
    WNDCLASSEX wcx={0};
    
    wcx.cbSize       =sizeof(wcx); 
    wcx.style        =0; 
    wcx.lpfnWndProc  =WndProc; 
    wcx.cbClsExtra   =0; 
    wcx.cbWndExtra   =0;
    wcx.hInstance    =hInst; 
    wcx.hIcon        =(HICON)LoadImage(0,IDI_APPLICATION,IMAGE_ICON,0,0,LR_SHARED); 
    wcx.hCursor      =(HCURSOR)LoadImage(0,IDC_ARROW,IMAGE_CURSOR,0,0,LR_SHARED);
    wcx.hbrBackground=(HBRUSH)(COLOR_BTNFACE+1); 
    wcx.lpszMenuName =0; 
    wcx.lpszClassName=classname; 
    wcx.hIconSm      =0; 
    
    if (RegisterClassEx(&wcx))
      {
      hwnd=CreateWindowEx(0,classname,
                          _T("Owner drawn button & subclassed static"),
                          WS_OVERLAPPEDWINDOW,
                          GetSystemMetrics(SM_CXSCREEN)/4,
                          GetSystemMetrics(SM_CYSCREEN)/4,
                          GetSystemMetrics(SM_CXSCREEN)/2,
                          GetSystemMetrics(SM_CYSCREEN)/2,
                          0,0,hInst,0);
      if (hwnd)
        {
        ShowWindow(hwnd,nCmd);
        UpdateWindow(hwnd);
        
        while (GetMessage(&msg,0,0,0)>0)
          {
          TranslateMessage(&msg);
          DispatchMessage(&msg);
          }
        return msg.wParam;
        }
      else
        {
        MessageBox(0,_T("Wnd creation failure"),_T("Error"),MB_OK|MB_ICONERROR);
        return 0;
        }
      }
    MessageBox(0,_T("Wnd registration failure"),_T("Error"),MB_OK|MB_ICONERROR);
    return 0;
    }
    /*===========================================================================*/
    LRESULT CALLBACK WndProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
    {
    switch (uMsg)
      {
      case WM_CREATE:
        return OnCreate(hwnd,(CREATESTRUCT*)lParam);
      case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
      case WM_DRAWITEM:
        OnDrawItem(hwnd,(DRAWITEMSTRUCT*)lParam);
        return TRUE;
      default:
        return DefWindowProc(hwnd,uMsg,wParam,lParam);
      }
    }
    /*===========================================================================*/
    int OnCreate(HWND hwnd,CREATESTRUCT *cs)
    {
    //subclassed static control
    CreateWindowEx(0,_T("BUTTON"),_T("Subclassed static control"),                      
                   WS_CHILD|WS_VISIBLE|BS_GROUPBOX,        
                   0,0,200,200,                                    
                   hwnd,                                  
                   0,                                   
                   cs->hInstance,                                
                   0);
    HWND hCntrl=CreateWindowEx(0,_T("STATIC"),0,                           
                               WS_CHILD|WS_VISIBLE|SS_ICON|SS_NOTIFY,   
                               10,80,40,40,                             
                               hwnd,                           
                               (HMENU)IDC_STATIC_ICON,                           
                               cs->hInstance,                        
                               0);  
    SendMessage(hCntrl,STM_SETIMAGE,IMAGE_ICON,(LPARAM)LoadImage(0,
                                                                 IDI_APPLICATION,
                                                                 IMAGE_ICON,
                                                                 0,0,LR_SHARED));   
    
    oldproc=(WNDPROC)SetWindowLongPtr(hCntrl,GWLP_WNDPROC,(LONG_PTR)CntrlProc);
    
    //ownerdrawn button
    CreateWindowEx(0,_T("BUTTON"),_T("Owner drawn button control"),                      
                   WS_CHILD|WS_VISIBLE|BS_GROUPBOX,        
                   204,0,200,200,                                    
                   hwnd,                                  
                   0,                                   
                   cs->hInstance,                                
                   0);
                   
    CreateWindowEx(0,_T("BUTTON"),0,                
                   WS_CHILD|WS_VISIBLE|BS_OWNERDRAW,  
                   240,80,80,40,
                   hwnd,
                   (HMENU)IDC_BUTTON,
                   cs->hInstance,0);
    return 0;
    }
    /*===========================================================================*/
    void OnDrawItem(HWND hwnd,DRAWITEMSTRUCT *ds)
    {
    //draw the button states
    HICON hIcon;
    FillRect(ds->hDC,&ds->rcItem,GetSysColorBrush(COLOR_BTNFACE));
    
    if (ds->itemState & ODS_SELECTED)
      {
      hIcon=(HICON)LoadImage(NULL,IDI_ASTERISK,IMAGE_ICON,0,0,LR_SHARED);
      }
    else
      {
      hIcon=(HICON)LoadImage(NULL,IDI_APPLICATION,IMAGE_ICON,0,0,LR_SHARED);
      }
    DrawIcon(ds->hDC,0,0,hIcon);
    }
    /*===========================================================================*/
    LRESULT CALLBACK CntrlProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
    {
    switch (uMsg)
      {
      case WM_LBUTTONDBLCLK:
      case WM_LBUTTONDOWN:
        SendMessage(hwnd,STM_SETIMAGE,IMAGE_ICON,
                    (LPARAM)LoadImage(0,IDI_ASTERISK,IMAGE_ICON,0,0,LR_SHARED));
        return CallWindowProc(oldproc,hwnd,uMsg,wParam,lParam);
      case WM_LBUTTONUP:
        SendMessage(hwnd,STM_SETIMAGE,IMAGE_ICON,
                    (LPARAM)LoadImage(0,IDI_APPLICATION,IMAGE_ICON,0,0,LR_SHARED));
        return CallWindowProc(oldproc,hwnd,uMsg,wParam,lParam);
      default:
        return CallWindowProc(oldproc,hwnd,uMsg,wParam,lParam);
      }
    }
    /*===========================================================================*/
    CProgramming FAQ
    Caution: this person may be a carrier of the misinformation virus.

  8. #8
    Registered User Tonto's Avatar
    Join Date
    Jun 2005
    Location
    New York
    Posts
    1,465
    Thank you muchly for the example code. I kind of forgot about this. However, I may be reverting to the windows 'default action' approach for this, or trying to at least.

    >> 1) The SDK docs say that pressing enter is equivalent to clicking the owning dialog's default button. So if your main window is or pretends to be a dialog, it would the corresponding notification.

    I'm trying to find where you said that, and what might be the default action for a window. I tried making a button with what I thought might be a default action by specifying the BS_DEFPUSHBUTTON style

    Code:
    	enterbtn = ::CreateWindowEx(0, TEXT("BUTTON"), TEXT("Go"), WS_CHILD | 
                                   WS_VISIBLE | BS_FLAT | BS_DEFPUSHBUTTON, 
                                   0, 0, 0, 0, hwnd, HMENU(IDC_BUTTON), 
                                    hInstance, 0);
    It created a very nice looking button, but I'm not sure whether it's the default action for the window or anything.

    Code:
          	case WM_COMMAND:
           	{
                if(lParam != 0)
                {
                    switch(::GetDlgCtrlID(HWND(lParam)))
                    {
                        case IDC_CHATTY:
                            errmsg("test1");
                            break;
                        case IDC_MAIN:
                            errmsg("test2");
                            break;
                        case IDC_BUTTON:
                            errmsg("test3");
                            break;
                    }
                }
                
                break;
            }
    I do not get WM_COMMAND notification from the button pressing enter in the IDC_CHATTY single line edit control, however I do get two WM_COMMAND notifications from just clicking on the IDC_CHATTY control.

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. Multiline Edit Box Parser
    By The Brain in forum Windows Programming
    Replies: 6
    Last Post: 11-01-2005, 07:15 PM
  3. Subclassing controls
    By filler_bunny in forum Windows Programming
    Replies: 3
    Last Post: 04-28-2004, 05:43 PM
  4. Dialog Edit Control and Enter Key
    By Quantrizi in forum Windows Programming
    Replies: 2
    Last Post: 04-14-2004, 07:59 AM
  5. Difficulty superclassing EDIT window class
    By cDir in forum Windows Programming
    Replies: 7
    Last Post: 02-21-2002, 05:06 PM