Results 1 to 13 of 13

Thread: Fill in a checkbox

  1. #1

    Thread Starter
    Lively Member
    Join Date
    Jul 2006
    Posts
    126

    Fill in a checkbox

    Hi,

    This is related to the earlier thread I started. This time, I have some checkboxes on the window that I want to check if they are checked and if not, I have to enable them. Now when I use the "Window Finder" tool I have to find the class of the checkboxes, I get that the "window" around them is from the class "Button"!! How is that possible? How can I get the checkboxes only? Thanks in advance!

  2. #2
    I'm about to be a PowerPoster! Joacim Andersson's Avatar
    Join Date
    Jan 1999
    Location
    Sweden
    Posts
    14,649

    Re: Fill in a checkbox

    A checkbox is a button with a different style, so they have the same class name (well a VB checkbox has a different class name compared to a VB command button, but the Windows controls have the same class name). To check the state of a checkbox (or an option button) simply send the BM_GETCHECK (=&HF0) message. It will return one of the following values:
    BST_CHECKED = (&H1) The item is checked
    BST_INDETERMINATE = (&H2) The button is "grayed checked"
    BST_UNCHECKED = (&H0) The item is not checked. This value is also returned if you're trying to send this message to a regular command button (push button).

  3. #3

    Thread Starter
    Lively Member
    Join Date
    Jul 2006
    Posts
    126

    Re: Fill in a checkbox

    Thx a lot Joacim. But I have several checkboxes that are under the same "Button" class. How can I check/uncheck a specific one?
    Something similar to searching child windows?

  4. #4
    I'm about to be a PowerPoster! Joacim Andersson's Avatar
    Join Date
    Jan 1999
    Location
    Sweden
    Posts
    14,649

    Re: Fill in a checkbox

    When you use FindWindowEx you will get the handle of the first control that matches the class name (and caption, if that is specified). To find the next you must pass the hWnd of the previously found control as the second argument of FindWindowEx. If you only use the class name "button" you will find each checkbox, pushbutton, and option button that exist for each subsequent call you make. If you want to find out that the found item indeed is a checkbox you'll need to check the style bits of the item.
    VB Code:
    1. Private Declare Function GetWindowLong Lib "user32.dll" Alias "GetWindowLongA" ( _
    2.     ByVal hWnd As Long, _
    3.     ByVal nIndex As Long _
    4. ) As Long
    5.  
    6. Private Const GWL_STYLE As Long = -16
    7. Private Const BS_CHECKBOX As Long = &H2&
    8. Private Const BS_3STATE As Long = &H5&
    9.  
    10. Public Function IsWindowCheckBox(ByVal hWnd As Long) As Boolean
    11.     Dim nStyle As Long
    12.     Dim b As Boolean
    13.     nStyle = GetWindowLong(hWnd, GWL_STYLE)
    14.     b = (((nStyle And BS_CHECKBOX) = BS_CHECKBOX) Or _
    15.          ((nStyle And BS_3STATE) = BS_3STATE))
    16.     IsWindowCheckBox = b
    17. End Function
    However if you know the caption of the checkbox simply specify that together with the class name in the call to FindWindowEx.

  5. #5

    Thread Starter
    Lively Member
    Join Date
    Jul 2006
    Posts
    126

    Re: Fill in a checkbox

    Thx a lot Joacim...I'll try what you wrote.

  6. #6
    I'm about to be a PowerPoster! Joacim Andersson's Avatar
    Join Date
    Jan 1999
    Location
    Sweden
    Posts
    14,649

    Re: Fill in a checkbox

    Once you have the handle to the correct checkbox you can either send BM_CLICK to it, however if the checkbox is in a dialog box the parent window has to have focus for that to work. You can also send BM_SETCHECK to it in which you specify the state you want the checkbox to get (regardless of the current state).
    VB Code:
    1. Call SendMessage(hCheckBoxWnd, BM_SETCHECK, BST_CHECKED, 0)

  7. #7

    Thread Starter
    Lively Member
    Join Date
    Jul 2006
    Posts
    126

    Re: Fill in a checkbox

    If I want to check/uncheck the box, can I use the constants that u wrote?
    Thanks.

  8. #8

    Thread Starter
    Lively Member
    Join Date
    Jul 2006
    Posts
    126

    Re: Fill in a checkbox

    Oh I didn't see that you wrote before I posted!
    Thx a lot!

    [Edit]: What is the value of BM_SETCHECK though? :S

  9. #9

    Thread Starter
    Lively Member
    Join Date
    Jul 2006
    Posts
    126

    Re: Fill in a checkbox

    It's &HF1. And it all works great! Thx a lot Joacim!

  10. #10

    Thread Starter
    Lively Member
    Join Date
    Jul 2006
    Posts
    126

    Re: Fill in a checkbox

    I'm wondering about one thing though. Is use the PostMessage API function to press a button in an application that should print some files. But sometimes the button doesn't get pressed (when I press it with the mouse, it continues working as normal)! When I used the SendMessage API function to press the button, it never returned (probably because when u press the button some other window appears and the button doesn't give a return value to SendMessage). So is there some secure way on how to be sure to press that button?

    Thanks in advance.

    [Edit]: Is it maybe good to use the SendMessageTimeout function for this?
    Last edited by Striver; Aug 3rd, 2006 at 12:12 PM.

  11. #11
    I'm about to be a PowerPoster! Joacim Andersson's Avatar
    Join Date
    Jan 1999
    Location
    Sweden
    Posts
    14,649

    Re: Fill in a checkbox

    Are you sending/posting the BM_CLICK message or using some other approach?

    In short the difference between SendMessage and PostMessage is that SendMessage sends the message directly to the specified window and waits for the message to be processed while PostMessage simply places the message in to the message queue of the thread that has created the window, so it doesn't wait for it to be processed. So the problem with using SendMessage is that it can wait forever while waiting for the window to process the message, which if the application has hung for some reason it may never do. While using PostMessage you'll never know if the message was successfully processed or not.

    Using SendMessageTimeout can be a good choice here since at least your application will not stop responding simply because a SendMessage call never returned. However it is not the solution to your problem about why the message never is processed.

  12. #12

    Thread Starter
    Lively Member
    Join Date
    Jul 2006
    Posts
    126

    Re: Fill in a checkbox

    Yes I am using the BM_CLICK message to click the button.

    Yeah that's exactly how I understood the difference between those two functions. Are there any other functions that are more safe to use? Because as soon as I change PostMessage to SendMessage, the program gets stuck. The button does get pressed (a "Print to file" window appears) but from there the program gets stuck and it never goes beyond the SendMessage call to the button. When I change it to PostMessage, it works, but I observed that sometimes it doesn't react. Maybe I could even loop in this case (as long as PostMessage returns 0) to get it right? Or maybe it's the case that it isn't 0 even if the button click isn't processed? I'll check that out. But could it really happen that the thread sometimes "jumps" over the message or something?

  13. #13
    I'm about to be a PowerPoster! Joacim Andersson's Avatar
    Join Date
    Jan 1999
    Location
    Sweden
    Posts
    14,649

    Re: Fill in a checkbox

    If the button brings up a modal dialog the SendMessage may not return until this new dialog is closed. This happens if the modal dialog is created by the same thread that created the button you click on, which is normally the case (in the same way the Click event in a VB program doesn't end its work until a modal form you bring up in the event procedure is closed).

    PostMessage would be the way to go here. As I mentioned earlier the BM_CLICK message might fail if the dialog owning the button doesn't have focus. Make sure that is the case before posting the BM_CLICK message. You can also try to send WM_LBUTTONDOWN followed by WM_LBUTTONUP to the button, that should automatically post a BM_CLICK message.
    Last edited by Joacim Andersson; Aug 3rd, 2006 at 04:12 PM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width