I have created in Visual Studio a MFC project which includes a cFileView, CDockablePane class.
As the image shows a item is selected and the menu is open. If I now klick on open the ON_COMMAND message will be called.
My problem is, how can I retrieve file name from the selected item. I have used
const MSG* pMsg = GetCurrentMessage();
HWND hWnd = HWND(pMsg->lParam);
In the pMsg pointer I can not find any item name "2020m7", only some x y coordinates.
How I can get the selected item name?
It is a CViewTree class. As in the image above you can see, the Item is selected.
HTREEITEM hItem = m_wndFileView.GetSelectedItem();
CString iText = m_wndFileView.GetItemText(hItem);
Therefore with the CViewTree pointer you can get the selected item and the item text via the HTREEITEM.
Nothing from the message is required.
Related
I have a TListView and when the user clicks on the image of an item (big green dot in picture below) i want to copy the item text ("russtest.cfg") and subitem text ("My Device, 1991") to display in a ShowMessage. I can't find how to do it in C++ Builder but this link shows how in Delphi.
Below is the code i've tried in the TListView's ItemClickEx method:
TListItem* item;
item = ListView1->Items->Item[ItemIndex];
UnicodeString s;
s = item->ToString();
ShowMessage(s);
But it brings back this:
EDIT 1: Added the code i use to populate the ListView:
TListViewItem* item2Add = Form1->ListView1->Items->Add();
Form1->ListView1->BeginUpdate();
item2Add->Text = mystring3; // e.g. "russtest.cfg"
item2Add->Detail = mystring2; // e.g. "My Device, 1991"
item2Add->ImageIndex = 1; // big green dot
Form1->ListView1->EndUpdate();
Your need to typecast the TListItem* to TListViewItem*, then you can access its Text property:
TListViewItem* item = static_cast<TListViewItem*>(ListView1->Items->Item[ItemIndex]);
String s = item->Text;
ShowMessage(s);
I am using VC6.0. I am trying programming to show contextmenu when I right click on the item of the ListBox. But now the popmenu can show anywhere in the rect of ListBox, since I only can get the rect of the ListBox, and I dont know how to get the rect of the item. I know that there is a macro ListView_GetSubItemRect which seems to get the rect of item of ListView. Is there similar way for ListBox, or is there a way to get the width and the height of item of ListBox, so I can caculate the rect? I didnt find some useful information on msdn and google? Can anyone give me some ideas? Thanks.
My current Code:
void My_OnContextMenu(HWND hwnd, HWND hwndContext, UINT xPos, UINT yPos)
{
HWND hList = GetDlgItem(hwnd,IDC_LIST_RESTYPE);
if (hList == hwndContext)
{
if(-1!=indexLB)
{
RECT rect;
POINT pt;
GetClientRect(hwndContext, &rect);
ScreenToClient(hwndContext, &pt);
if(PtInRect(&rect, pt))
{
HMENU hroot = LoadMenu((HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE), MAKEINTRESOURCE(IDR_MENU_DELTYPE));
if(hroot)
{
HMENU hpop = GetSubMenu(hroot,0);
ClientToScreen(hwndContext, &pt);
TrackPopupMenu(hpop, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RIGHTBUTTON, pt.x, pt.y, 0, hwndContext, NULL);
DestroyMenu(hroot);
}
}
}
}
}
Edit
Current:
First, I left click an item to selected、 an item. And Second I right click the selected item to show popmenu. It shows normally. But in the second step if I click the blank area of ListBox, it shows menu either. That is not what I expected.
What I expected is:
The menu only shows when I click an item and the position only over the item. When I right click other area, it wont be showed.
You are looking for the ListBox_GetItemRect macro.
However, I do feel that the user will find it odd to click in one place and see the menu appear somewhere else.
The proper solution to this problem is to popup the context menu at the mouse position. Clicking in one place and popping it up somewhere else would be very bad.
To get the mouse position use GetCursorPos().
http://msdn.microsoft.com/en-us/library/windows/desktop/ms648390%28v=vs.85%29.aspx
To be clear, first use ListBox_GetItemRect to work out which item is clicked on, and ignore it if none. Then use GetCursorPos so the menu appears exactly where the mouse is -- inside the list item -- and not somewhere a few pixels away. The Windows UI standards are that the context menu appears at the cursor position.
I'm not sure Why you wrote your own OnContextMenu - you should use the class wizard to map WM_CONTEXTMENU with the standard handler where the existing function ends up in your code like this:
//Wizard Added this the message map block
ON_WM_CONTEXTMENU()
//Declares the function with the proper parameters
void MyDlg::OnContextMenu(CWnd* pWnd, CPoint point);
//in the body of OnContextMenu use the system supplied parameters and the
//menu will appear next to the mouse position wherever it is clicked in the control
CMenu popupmenu;
popupmenu.LoadMenu(IDR_RMOUSEPOPUP);
int Command = (int)popupmenu.GetSubMenu(0)->TrackPopupMenu(
TPM_LEFTALIGN | TPM_BOTTOMALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD | TPM_NONOTIFY,
point.x, point.y, pWnd);
I am trying to use the IFileOpenDialog to pick both files and folders (in multi-select mode) from the same dialog. I was able to add a custom button to the dialog and achieve what i want to do. Now i want to remove the default "Open" button from the dialog because its behavior is dependent on the order of selection. If a file is selected first and then a folder (multiselect), I get the OnFileOk event but if a user selects a folder first then a file, a click on the open button opens the first selected folder. Is there a way to remove or hide the Open button ??
My idea was to enumerate the child windows of IFileDialog and remove the child with caption "Open" and class "Button". I tried enumerating the child windows of IFileOpenDialog before doing the show, but I get only one child with class "Button" but its caption is "start". I cannot find a standard way of hiding the "Open" button. Please let me know if there is any other way of doing this.
Thanks,
Abhinay.
Buke's method worked for me but you have to wait until the dialog controls are created. It seems like every time the dialog is created OnFolderChange() is called so I just added my hiding code there:
STDMETHODIMP FileDialogEventHandler::OnFolderChange(IFileDialog* fileDialog) {
IOleWindow *pWindow = NULL;
HRESULT hr = fileDialog->QueryInterface(IID_PPV_ARGS(&pWindow));
if (SUCCEEDED(hr)) {
HWND hwndDialog;
hr = pWindow->GetWindow(&hwndDialog);
HWND openButton = GetDlgItem(hwndDialog, IDOK);
ShowWindow(openButton, SW_HIDE);
pWindow->Release();
}
return S_OK;
}
If you know the dialog item number (You can find the button ID using Spyxx), you may be able to do something like this:
HWND hOpenButton = GetDlgItem( hDlg, itemID );
ShowWindow( hOpwnButton, SW_HIDE );
IFileDialogCustomize::RemoveControlItem
We have a problem with an ATL-based Visual C++ MMC snapin. We have a scope item that is only showed in the scope pane. When this item is selected it populates the result pane with a set of result items.
When the user selects "delete all items" popup menu command our snapin code is invoked - first it does some work, then proceeds to clearing the result view. We want the following behavior: the user clicks that menu item, our custom code is called to do useful work, then all items disappear from the result pane, the scope item remains selected.
I tried two variations of what to do to remove all result items.
Variation 1 - it calls IResultData::DeleteAllRsltItems() which returns E_UNEXPECTED and items are not removed - they just stay there.
VAriation 2 - it calls IResultData::DeleteItem() for each item previosuly inserted into result pane. Again each call returns E_UNEXPECTED and items are not removed.
How do I properly remove all result items from the MMC view?
We do this in the OnShow handler. All child items are removed like this:
CComPtr<IResultData> pResultData;
result = pConsole->QueryInterface(IID_IResultData, (void **)&pResultData);
assert( SUCCEEDED(result) );
pResultData->DeleteAllRsltItems();
Then re-added:
RESULTDATAITEM rdi;
ZeroMemory(&rdi, sizeof(RESULTDATAITEM) );
rdi.mask = RDI_STR | RDI_IMAGE | RDI_PARAM;
rdi.nImage = m_resultChildren[i]->GetBitmapIndex();
rdi.str = reinterpret_cast< wchar_t* >(MMC_CALLBACK);
rdi.nCol = 0;
rdi.lParam = (LPARAM)m_resultChildren[i].get();
HRESULT result = pResultData->InsertItem( &rdi );
This works to remove the result items. I assume that you have another problem in the code that is causing the E_UNEXPECTED.
I writing a MFC which has a listview control. When the user right clicks any item , I am generating a dynamic menu item with that text that is selected in listview. Everything is displaying properly, but I do not know how to add a message map to that dynamic menu item.
Any help?
void CMyListDlg::OnRclickList(NMHDR* pNMHDR, LRESULT* pResult)
{
// TODO: Add your control notification handler code here
int nIndex = m_List.GetSelectionMark();
CString pString = m_List.GetItemText(nIndex,1);
CMenu menu, * pSubMenu;
int pos=0;
menu.LoadMenu(IDR_MENU1);
pSubMenu = menu.GetSubMenu (0);
pSubMenu->DeleteMenu(0,MF_BYPOSITION);
pSubMenu->InsertMenu(pos,MF_BYPOSITION,NULL,pString);
CPoint oPoint;
GetCursorPos (& oPoint);
pSubMenu-> TrackPopupMenu (TPM_LEFTALIGN, oPoint.x, oPoint.y, this);
*pResult = 0;
}
At the moment you are inserting the menu item with ID = 0 (NULL). That way you can't figure out which command was pressed. You have to assign an ID to the item, the simplest one is to
#define WM_MYMESSAGE WM_USER + 1
then you insert it like this:
pSubMenu->InsertMenu(pos,MF_BYPOSITION,WM_MYMESSAGE,pString);
If you override OnCommand for your window, you get your ID as wParam.
To actually figure out what happened, store some additional information in another class member, like m_nLastItemClicked or ... you get the idea?!
Check the MFCIE sample, it generates a favorite menu from the user's favorite folder and navigates to the favorite url when a favorite menu item is clicked.
Just add ON_COMMAND (and ON_UPDATE_COMMAND_UI if necessary) handlers for the menu items' IDs on your class.