Announcement

Collapse
No announcement yet.

Global WM_SETFOCUS and WM_KILLFOCUS

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Dominic Mitchell
    replied
    Actually, there is no need to worry about control identifiers.
    In a data entry dialog, the label controls are used to inform the user about the purpose
    of the edit field. They also provide the mnemonic that is used to set the focus to the
    edit field when the user presses the Alt+<mnemonic> keys. In order for the correct edit
    field to receive the focus when the user presses the mnemonic, the edit control is created
    immediately after its associated label.
    This means that if the dialog is laid out properly, the subclass procedure would look like
    that shown below.
    The same logic can be used for EN_SETFOCUS/EN_KILLFOCUS.

    Note:
    g_hFontBold -> global variable for bold font
    g_hFont -> global variable for normal font


    Code:
    FUNCTION SubclassProc _
      ( _
      BYVAL hWnd    AS DWORD, _ ' control handle
      BYVAL uMsg    AS DWORD, _ ' type of message
      BYVAL wParam  AS DWORD, _ ' first message parameter
      BYVAL lParam  AS LONG _   ' second message parameter
      ) EXPORT AS LONG
    
      LOCAL hWndLabel       AS DWORD  
      LOCAL lpOldWndProc    AS DWORD    ' address of original window procedure
    
      lpOldWndProc = GetProp(hWnd, "OLDWNDPROC")
    
      SELECT CASE uMsg
        CASE %WM_SETFOCUS
          hWndLabel = GetWindow(hWnd, %GW_HWNDPREV)
          SendMessage hWndLabel, %WM_SETFONT, g_hFontBold, %TRUE
      
        CASE %WM_KILLFOCUS
          hWndLabel = GetWindow(hWnd, %GW_HWNDPREV)
          SendMessage hWndLabel, %WM_SETFONT, g_hFont, %TRUE
      
        CASE %WM_DESTROY
          ' Remove control subclassing
          SetWindowLong hWnd, %GWL_WNDPROC, RemoveProp(hWnd, "OLDWNDPROC")
      END SELECT
    
      FUNCTION = CallWindowProc(lpOldWndProc, hWnd, uMsg, wParam, lParam)
    
    END FUNCTION

    Leave a comment:


  • Dale Yarker
    replied
    Since the labels (as used in this range) won't be getting focus, I didn't worry about filtering them out. They fail the next nested IF.

    If you want, try instead:
    Code:
    if (cbctl > 1023) and (cbctl < 1057) AND ((cbctl AND &h00000001) = 0)THEN
    When possible I use logic operators rather than arithmetic operators. For powers of 2, AND with mask is equivilent to MOD, and faster than dividing.

    With some more thinking, and using other than bit 0 to differentiate between a textbox and it's associated label, the greater than and less than could be replaced too. But it wouldn't be as clear to the original poster.

    C U L -

    Leave a comment:


  • Michael Mattias
    replied
    >When a textbox or combo box (even numbered) gets focus
    Code:
            if (cbctl > 1023) and (cbctl < 1057) [B]AND (cbctl mod 2 = 0)[/B] THEN

    Leave a comment:


  • Dale Yarker
    replied
    Re: WM_SET|KILL FOCUS vs EN_SET|KILL FOCUS, you are correct, I just copied/pasted from original post. (that wipes out a dozen ataboys )

    Yeah only odd controls. When a textbox or combo box (even numbered) gets focus, the label (odd numbered) for that control gets a bold font. And the label for the control that lost focus is returned to normal weight font. And done without repeating the code in the CASE for each textbox/combobox.
    Last edited by Dale Yarker; 4 May 2008, 11:08 AM.

    Leave a comment:


  • Michael Mattias
    replied
    For edit (textbox) controls you don't want to look for WM_COMMAND + WM_SET|KILL FOCUS, you want to look for WM_COMMAND + EN_SET|KILL FOCUS

    >control post cbhndl, cbctl or 1, %WM_SETFONT, hFontBold, 0

    OR 1?

    Message will be posted to CtrlId + 1 ("the wrong control") when CtrlID is an even number. Oops. (But it will be just fine for odd-numbered controls.)

    MCM

    Leave a comment:


  • Dale Yarker
    replied
    Try:
    Assign IDs of controls as even numbers, IDs of associated label plus 1.
    For 16, or less, controls; ID range could be 1024 to 1057. Assign other controls to IDs outside this range.

    Logic OR cbctl with 1 to get ID of label.

    example:
    Code:
    %ID_TxtBx1 = 1024
    %ID_Label1 = 1025
    %ID_TxtBx2 = 1026
    %ID_Label2 = 1027
    ...
    %ID_Button1 = 1058
      ...
      ...
        case %WM_COMMAND
          'bold label for control with focus
          if (cbctl > 1023) and (cbctl < 1057) then 'range of controls with this behavier
            if cbctlmsg = %EN_SETFOCUS then
               control post cbhndl, cbctl or 1, %WM_SETFONT, hFontBold, 0
            elseif cbctlmsg = %EN_KILLFOCUS then
               control post cbhndl, cbctl or 1, %WM_SETFONT, hFontNormal, 0
            end if
          end if
          select case as long cbctl '<-- usual control processing code
            case %ID_Button1
      ...
    (changed cbctlmsg names, see next 2 posts)
    Last edited by Dale Yarker; 4 May 2008, 11:09 AM. Reason: change control send to control post

    Leave a comment:


  • Dominic Mitchell
    replied
    One way to do this is to subclass the controls and use the same subclassed procedure
    for all of them.
    But in order for this to work, you will have to save the pointer to the original procedure
    for each control as a window property. For example,
    Code:
    SetProp hWndControl, "OLDWNDPROC", SetWindowLong(hWndControl, %GWL_WNDPROC, CODEPTR(SubclassProc))
    Then the subclass procedure will look something like this
    Code:
    FUNCTION SubclassProc _
      ( _
      BYVAL hWnd    AS DWORD, _ ' control handle
      BYVAL uMsg    AS DWORD, _ ' type of message
      BYVAL wParam  AS DWORD, _ ' first message parameter
      BYVAL lParam  AS LONG _   ' second message parameter
      ) EXPORT AS LONG
    
      LOCAL lpOldWndProc    AS DWORD    ' address of original window procedure
    
      lpOldWndProc = GetProp(hWnd, "OLDWNDPROC")
    
      SELECT CASE uMsg
        CASE %WM_SETFOCUS
          
        CASE %WM_KILLFOCUS
            
        CASE %WM_DESTROY
          ' Remove control subclassing
          SetWindowLong hWnd, %GWL_WNDPROC, RemoveProp(hWnd, "OLDWNDPROC")
      END SELECT
    
      FUNCTION = CallWindowProc(lpOldWndProc, hWnd, uMsg, wParam, lParam)
    
    END FUNCTION

    Leave a comment:


  • John Thompson
    started a topic Global WM_SETFOCUS and WM_KILLFOCUS

    Global WM_SETFOCUS and WM_KILLFOCUS

    I've got multiple windows with ten-plus controls (mostly textboxes, but some comboboxes, etc.) used for data entry. I wanted to set the font of the label for each control to bold when it has the focus. My issue is that from my understanding, I need to include a WM_SETFOCUS and WM_KILLFOCUS for EACH control. This is not un-doable, but I would prefer only one set of WM_SETFOCUS and WM_KILLFOCUS that handle all controls on the page. Is this possible?

    Thanks!

    -JT
Working...
X