Can't find the information you are looking for here? Then leave a message over on our WinBatch Tech Support Forum.
Keywords: Determining if Check Boxes are Checked LONG ANSWER
; This is an example of sending mouse clicks to controls in a dialog box. ; Some message numbers, obtained from the WINDOWS.H header file. BMGETCHECK = 1024 BMSETCHECK = 1025 WMLBUTTONDOWN = 513 WMLBUTTONUP = 514 Run("notepad.exe", "") SendMenusTo("Notepad", "Search | Find") ; Get window handle of "Find" dialog. hWnd = DllHwnd("Find") If hWnd == 0 Message("Error", "Parent window not found") Goto cancel Endif ; We will be using several functions from this DLL. dll = DllLoad("user.exe") ; Allocate a binary buffer. buffer = BinaryAlloc(80) ; This is just for visual demonstration purposes. It is not needed. WinActivate("Find") ; All the Delay's are just so you can see what is happening. Not needed. Delay(1) ; This call finds the first child window belonging to the specified parent. ; We won't need the paren't handle anymore, so we'll just re-use the hWnd ; variable. GetWindow, last parm == 5, means find first child of this parent. hWnd = DllCall(dll, word:"GetWindow", word:hWnd, word:5) ; We will keep a running sequence. i = 0 ; Keep looping until we run out of children. While hWnd != 0 ; We will go through this loop for each child window (control) in the dialog. i = i + 1 ; Get the text associated with this child window (a control of some sort), ; and store it in our binary buffer. The last parameter is the max length. len = DllCall(dll, word:"GetWindowText", word:hWnd, lpbinary:buffer, word:80) ; Set the BinaryEod to the length of the string we got back. BinaryEodSet(buffer, len) ; Get the contents of the binary buffer into a string. text = BinaryPeekStr(buffer, 0, len) ; Remove the '&' from the text. The programmer puts an '&' in front of ; the character he wants underlined, so "Cancel" would look like "&Cancel". text = StrReplace(text, "&", "") ; Trim off any leading or trailing spaces. text = StrTrim(text) ; Now we have the name of the control. If you want, you can use StrLower ; to make it lower case, or use StrCmpi to do a case-insensitive comparison, ; but in this example we will do a case-sensitive comparison because we know ; exactly what we are looking for. We are looking for 4 different controls ; to play with here; if you are just trying to modify a single control, your ; If...Else structure will be much less complicated. ; Un-comment to display the control's sequence and text, for demo purposes. ;Display(1, i, text) ; This is a checkbox. If text == "Match Case" ; We will see if it is checked. The last 2 parameters of BM_GETCHECK are ; both always 0. chk=DllCall(dll,long:"SendMessage",word:hWnd,word:BMGETCHECK,word:0,long:0) ; And we will toggle the current state. If all you want to do is ; unconditionally check or uncheck it, you do not need the previous ; command, and you do not need an If...Else statement here. Just do it. ; You will notice that we are using an IntControl here to send the message ; instead of using DllCall. The only reason we used DllCall to send the ; previous BM_GETCHECK message was because we needed to get a return value, ; and IntControl(23) doesn't receive a return value. But when we send the ; BM_SETCHECK message, we don't care about the return value, so it is ; easier and more efficient to use the IntControl. The last parameter of ; BM_SETCHECK is always 0. If chk == @OFF IntControl(23, hWnd, BMSETCHECK, @ON, 0) Else IntControl(23, hWnd, BMSETCHECK, @OFF, 0) Endif Delay(1) Else ; This is a set of two radio buttons, and is a little more complicated, ; because if you check one, you should uncheck the other(s) in the set. ; When you do it with the mouse or keyboard, this happens automatically, ; but we will have to do it manually. We want to check the "Up" button. If text == "Up" IntControl(23, hWnd, BMSETCHECK, @ON, 0) Delay(1) Else ; Actually, you really don't need to uncheck the "Down" button, because ; internally it has been de-selected, but it looks kind of funny to have ; them both checked on the screen. It's your choice. We'll uncheck it. If text == "Down" IntControl(23, hWnd, BMSETCHECK, @OFF, 0) Delay(1) Else ; Now let's press the Cancel button. If text == "Cancel" ; The first parameter for WM_LBUTTONDOWN is the state of the shift ; and control keys and the middle and right mouse buttons, in this ; case none of them are down. The second parameter is the cursor ; coordinates in the child window (ie, in the button). These ; coordinates are actually somewhat complicated to figure out, but ; fortunately we don't need to, since pressing the mouse anywhere on ; the button gets the job done. If you un-commented the Display ; line above, this command may not actually close the Find dialog. IntControl(23, hWnd, WMLBUTTONDOWN, 0, 0) Delay(1) ; Now we send a message saying that we released the button. Not ; strictly necessary, but good practice. Same parameters as before. IntControl(23, hWnd, WMLBUTTONUP, 0, 0) Delay(1) Endif Endif Endif Endif ; Okay, we just processed one (more) control. Now we will get the handle of ; the next child, if any (the loop ends when we get a handle of 0), and ; again we will just re-use the hWnd variable since it makes life easier. ; GetWindow, last parm == 2, means find next sibling of this child window. hWnd = DllCall(dll, word:"GetWindow", word:hWnd, word:2) EndWhile ; At this point, we have seen every child window in the "Find dialog". You ; may have noticed there were some child windows that had no names; they ; were not significant. If you need to process a control in a different ; dialog that has no name, you can use its positional sequence number (i). ; You may also have noticed some child windows that you didn't see on the ; screen. I can't begin to tell you why. Get a book on Windows programming. ; Clean up. :cancel BinaryFree(buffer) DllFree(dll) WinClose("Notepad")
One minor correction to my example:
Now we send a message saying that we released the button. Not strictly necessary, but good practice. Same parameters as before.
IntControl(23, hWnd, WMLBUTTONUP, 0, 0)
Actually, for a pushbutton like the "Cancel" button, it *is* necessary to send this message. For some other types of controls and windows, it's not strictly necessary (eg, for a copyright screen which disappears as soon as you send a WM_LBUTTONDOWN -- you don't need to send a WM_LBUTTONUP because the window will be gone anyway), but it's always good practice to do so.