We're trying to use QTP (QuickTest Professional) to auto-test a legacy C++ application.
However, the main window for the app is composed of several IDENTICAL panels. Each panel has a unique title.
If I view the window in Spy++ (comes with DevStudio), I see:
+ Window <hwnd> "Window Title" taskwindowclass
+ Window <hwnd> "Panel A" childwindowclass
+ Window <hwnd> "OK" Button
+ Window <hwnd> "Panel B" childwindowclass
+ Window <hwnd> "OK" Button
In QTP's Object Spy however, the hierarchy shows as:
+ Window: Window Title
+ WinButton: OK
It doesn't even show that there is an intermediate panel.
Does anybody know a way to get the window "path" in order to identify each control?
i.e. so the controls identify as:
Button A: "Window Title/Panel A/OK"
Button B: "Window Title/Panel B/OK"
You could use descriptive programming to bypass the object map. QTP will ignore panel objects by default. You could try to get a reference to the panel object dynamically, then search the ChildObjects collection to find the ok button. Another option might be to simply add an ordinal identifier to the ok buttons.
Button A: "Window Title/OK index #1"
Button B: "Window Title/OK index #2"
Related
I am really struggling how to make a window with three selections of options. I currently have a setup that uses a CFileDialog object and have successfully implemented two dropdown menus and multiple check items.
What I want is to implement a pop up window that has the two drop down menus and the check boxes. If a certain item is selected in one of the dropdown menus then the file dialog is opened.
Currently I am trying to make a CWnd object and try to write code for it there.
CWnd myWindow;
BOOL VALUE = myWindow.Create(_T("DesktopApp"), _T("test"), WS_VISIBLE | WS_BORDER | WS_CAPTION,
RECT{ 100,100,400,400 },
myWindow.GetDesktopWindow(), 12);
myWindow.ShowWindow(SW_SHOWNORMAL);
if (VALUE == FALSE) {
return 0;
}
Every time I run this, it prematurely returns (VALUE == FALSE). Did I do something wrong? Is there a simpler way to create a window?
The first argument to CWnd::Create is the window class name. A class with the requested name must have been registered before it can be created.
It is common to register an application local class for the application's main window. MFC provides a convenient wrapper function (AfxRegisterWndClass) to register a window class.
I have a tree view (CTreeView) that will show me a pop-up menu after I right-click my mouse on it.
In my context menu there are only 3 items (i.e A, B, C) for selection and my tree view displays a long list of ordered foods designed with check-boxes. I would like to disable menu items A and B if no ordered foods are checked and enable them when any is.
I create CFoodView::OnUpdateItemA(CCmdUI* pCmdUI) //CFoodView inherits CTreeView
and CFoodView::OnUpdateItemB(CCmdUI* pCmdUI) to handle their states like so
CFoodView::OnUpdateItemB(CCmdUI* pCmdUI)
{
if TreeView has no items
{
pCmdUI->Enable(FALSE);
}
else
{
*Search* the tree to get selected items
if None is checked
{
pCmdUI->Enable(FALSE);
}
else there are checked items
pCmdUI->Enable(TRUE);
}
}
Method CFoodView::OnUpdateItemA(CCmdUI* pCmdUI) is the same.
I think this isn't a correct way to handle this GUI feature.
Well, you did not submit all important information. How did you create menu item handlers?
Assuming you insert handlers the proper way, still did not provide any information how you are invoking popup menu.
If all you did was properly done it is the proper way of handling update menu.
The most common mistake is designating view itself as the window that handles popup updates and commands. In order to use MFC menu update mechanism, you have to pass a pointer to the main window not to the tree view:
CWnd *pMainWnd = AfxGetMainWnd();
ASSERT(pMainWnd != nullptr);
pSubMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, pt.x, pt.y, pMainWnd);
If this will not work reexamine the way you create handler and/or the place you invoke the TrackPopupMenu function.
byIs there are bug in control ? or I am doing something wrong ?
In .h
CMFCToolBar m_wndToolBar;
in message map
ON_COMMAND(ID_MYID, &CMainFrame::OnToolBar)
void CMainFrame::OnToolBar()
{
int nIndex = m_wndToolBar.CommandToIndex(ID_MYID);
UINT nState = m_wndToolBar.GetButtonStyle(nIndex);
if(nState & TBBS_PRESSED)
nState &= ~TBBS_PRESSED;
else
nState |= TBBS_PRESSED;
m_wndToolBar.SetButtonStyle(nIndex,nState);
m_wndToolBar.InvalidateButton(nIndex);
}
By clicking on button I need to set button pressed, and when user clicked again, button become unpressed.
Nothing happens by clicking on button :(
Just create an ON_UPDATE_COMMAND handler for the specific item.
Use pCmdUI->SetCheck to Signal the down or Up state.
The MFC updates tool bars and menus never directly. They ask the Framework to update the state of the Buttons and menu items.
Your description indicates that you want the button to have the behavior of a "check box". If that is correct, make sure you specify TBBS_CHECKBOX for the button style. You should not need to manually handle rendering the check box state each time the button is pressed.
I have a dialog application in which I want to have clickable menu items at the top of the dialog. These items do not show a drop down menu but actually run the associated commands.
I did this by setting Popup=False in the dialogs properties and assigning a message-id but my problem is not having the ability to disable the item properly when it makes no sense for the item to be clickable (depending on internal state stored in the dialog)
I have already found out how to disable any popup-parent menu items from http://www.microsoft.com/msj/0299/c/c0299.aspx, but this isn't exactly what I want
I have also found out how to add menu command routing to dialogs from the msdn knowledgebase article KB242577.
This works fine for sub-menu items, but not for the top level menu.
I am currently using the following function to do the disabling
void CYourDlg::EnableMenuItem(UINT nCommand, BOOL bEnable)
{
CMenu* pMenu = GetMenu();
pMenu->EnableMenuItem(nCommand, bEnable ? 0 : MF_DISABLED | MF_GRAYED);
}
This half works, if you alt-tab away from the app it does show as disabled, otherwise it doesn't.
Is there a way to invalidate the area programmatically?
I think an non-client area message may be involved.
I have not tried but in regular window (not dialog) CWnd::DrawMenuBar should do what you want. It might work with dialog based applications as well.
void CYourDlg::EnableMenuItem(UINT nCommand, BOOL bEnable)
{
CMenu* pMenu = GetMenu();
pMenu->EnableMenuItem(nCommand, bEnable ? 0 : MF_DISABLED | MF_GRAYED);
DrawMenuBar();
}
I think you should add an ON_UPDATE handler for your menu ID. This would ensure that the menu is enabled/disabled when you want to.
Building a file open dialog replacement. Much of it works now, but I would like to generate the view-mode drop-down for the toolbar directly from the shell view object.
Looking at IShellView2, I can see IShellView2::GetView() will give me the FOLDERVIEWMODE's supported. However, that doesn't give me the names of these modes, nor format that popup menu for me, nor immediately give me a way to actually set one of those modes (it would appear it is necessary to destroy the shell view window and create a replacement one for the current folder and specify the new FOLDERVIEWMODE desired... yeesh).
At any rate, if one right clicks on an IShellView window, one gets a context menu, the first submenu of which is exactly what I want to place in my drop-down toolbar button (ie. the "view" fly-out menu (e.g. Small Icons, Medium Icons, etc.)).
It seems like there ought to be a way to grab that submenu directly from the IShellView, rather than having to hardcode my values (and that way, if a given instance of IShellView supports extra view modes, they'd be there. Similarly, those which should be disabled would be, since it would all be under the IShellView's control).
I have read Raymond Chen's excellent How to host an IContextMenu. Unfortunately, that just gives me a very simplistic context menu - the one for the folder itself, or for a file in a given folder, but NOT the context menu for the IShellView's shell view window (from which I might obtain the view fly-out).
I have tried the following, based on Chen's article:
CComQIPtr<IContextMenu> pcm(m_shell_view); // <<-- FAIL resulting pointer is NULL <<<
// create a blank menu
CMenu menu;
if (!menu.CreatePopupMenu())
throw CContextException("Unable to create an empty menu in which to store the context menu: ");
// obtain the full popup menu we need
if (FAILED(m_hresult = pcm->QueryContextMenu(menu, 0, SCRATCH_QCM_FIRST, SCRATCH_QCM_LAST, CMF_NORMAL)))
throw CLabeledException("Unable to query the context menu for the current folder");
// display the menu to the user
// menu.getsubmenu
::TrackPopupMenu(menu, ::GetSystemMetrics(SM_MENUDROPALIGNMENT)|TPM_TOPALIGN|TPM_LEFTBUTTON, pt.x, pt.y, 0, m_shell_view_hwnd, NULL);
Unfortunately, the attempt to query the m_shell_view (which is an IShellView*) for its IContextMenu interface fails. This "works":
// retrieve our current folder's PIDL
PidlUtils::Pidl pidl(m_folder);
// get the context menu for the current folder
CComPtr<IContextMenu> pcm;
if (FAILED(m_hresult = GetUIObjectOf(m_owner->m_hWnd, pidl, IID_PPV_ARGS(&pcm))))
throw CLabeledException("Unable to obtain the PIDL for the current folder");
But here I get only a very few options in the context menu (Open, Explore, ...). Not the detailed context menu that I get if I simply right click on the shell view itself.
I'm out of ideas as to how to proceed. Help?! ;)
Try IShellView::GetItemObject with SVGIO_BACKGROUND as uItem to get a IContextMenu on the view object : http://msdn.microsoft.com/en-us/library/bb774832%28VS.85%29.aspx
There is the SHCreateDefaultContextMenu (Vista an up) that may be of help. Bjarke Viksoe website contains great info as well.
SVGIO_BACKGROUND will get you the background context menu of the shell view. You may need to call repeatedly pShellView->SelectItem for each PIDL you may have, then do the GetUIObjectOf call (then QI for IContextMenu, create a menu, call IContextMenu(3)::QueryContextMenu and finally display it with TrackPopupMenu).