Find window handle of a ribbon button
I'm trying to do some automation of windows applications. To do whatever I want to do, I need the window handles of some controls.
Before, I would accomplish this with a combination EnumWindows, EnumChildWindows and GetWindowText. But now, some newer programs no longer have toolbar with buttons on it. Instead, they have a ribbon.
This didn't seem like much of a problem to me at first, but now I notice that the buttons on the ribbon don't show up in EnumChildWindows! Or at least GetWindowText does not return the same text as the one seen on the scr开发者_开发知识库een.
So to make a long story short: Can anybody tell me how I can programatically find the handle of a button on a ribbon?
Thanks. Regards, ldx
Use Spy++ shipped with Visual Studio (or any other similar tool) to see if these buttons are actually windows. If yes, see the detailed information about them using that tool. However, it's very likely that this app draws them by itself on the parent window context, in which case you can't get the window handle because they are not real windows.
Simply put, I don't think you can. More and more windows applications are using GUI frameworks that do not render controls with discreet child windows. The Ribbon UI framework seems to be one of those.
The only way to enumerate controls in an application that doesn't use child windows is to use the accessibility APIs: Windows Automation API: UI Automation is the starting point in the documentation.
Okay,
So it was indeed not possible to get a handle on these buttons. I solved this by using SendKeys to send the keyboard-shortcut that activates the button. In my case it was the save button, so I used
INPUT inputs[4];
// press control
inputs[0].type = INPUT_KEYBOARD;
inputs[0].ki.wVk = 0x11; // "VK_Control"
inputs[0].ki.wScan = 0;
inputs[0].ki.dwFlags = 0;
inputs[0].ki.time = 0;
inputs[0].ki.dwExtraInfo = 0;
// press "s"
inputs[1].type = INPUT_KEYBOARD;
inputs[1].ki.wVk = 0x53; // "s"
inputs[1].ki.wScan = 0;
inputs[1].ki.dwFlags = 0;
inputs[1].ki.time = 0;
inputs[1].ki.dwExtraInfo = 0;
// release "s"
inputs[2].type = INPUT_KEYBOARD;
inputs[2].ki.wVk = 0x53; // "s"
inputs[2].ki.wScan = 0;
inputs[2].ki.dwFlags = KEYEVENTF_KEYUP;
inputs[2].ki.time = 0;
inputs[2].ki.dwExtraInfo = 0;
// release control
inputs[3].type = INPUT_KEYBOARD;
inputs[3].ki.wVk = 0x11; // "VK_Control"
inputs[3].ki.wScan = 0;
inputs[3].ki.dwFlags = KEYEVENTF_KEYUP;
inputs[3].ki.time = 0;
inputs[3].ki.dwExtraInfo = 0;
return SendInput(8, inputs, sizeof(INPUT)) == 8;
Maybe this can spawn ideas for other people with the same problem :)
Gr, ldx
You can have the handle of the window that you call a ribbon. But you can't have a handle on what you call a button.
Logically: what do you call a handle ? do you want a HWND ? If you want a HWND then you need to a a window... but the only window you have is the ribbon.
This is called windowless programming.
However you could use a COM technology component: the COM interface IAccesible.
may be this could give some guidance? http://msgroups.net/microsoft.public.excel.programming/Get-a-specifc-button-Handle-inside-ribbon
精彩评论