关于如果显示系统菜单的问题

fbmsyu 2009-01-19 12:40:37
[描述]Form1 上面有一个button1, c:盘有个文件a.txt.

[需求]怎么实现,鼠标右键点击button1时,鼠标右键显示一个a.txt的系统菜单menu1.
也就是menu1显示的内容,要和在资源管理器里面右键直接点a.txt里面显示的内容一样.比如,打开,,添加到压缩文件,复制粘贴,删除,重命名,属性.
...全文
175 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
yumikoo 2009-01-19
  • 打赏
  • 举报
回复
首先要自定义好menu1的选项与Button关联
再则,定义好menu1各项菜单的消息命令,映射a.txt的各项消息,比如复制copyfile,删除deletefile,重命名rename等等,可能稍微难点的是属性,这个代码我在前两天一张帖子里有回复。
fbmsyu 2009-01-19
  • 打赏
  • 举报
回复
6楼写的不对.
目前这段代码还是有点问题,send to 文件夹里面的东西不能显示.正在找原因...
jaffy 2009-01-19
  • 打赏
  • 举报
回复
哦,这是个好代码,收藏
ydlchina 2009-01-19
  • 打赏
  • 举报
回复
学习
TripH0101 2009-01-19
  • 打赏
  • 举报
回复
恭喜
fbmsyu 2009-01-19
  • 打赏
  • 举报
回复
该文章自定义了菜单,并且写道
if (Cmd < 100&& Cmd != 0)

这里100这个数字太小了,在我的计算机上要写成1000才能调用UE,压缩命令.因为第三方程序自定义的id也许很大.
fbmsyu 2009-01-19
  • 打赏
  • 举报
回复
找到答案了.

http://delphi.ktop.com.tw/board.php?cid=168&fid=914&tid=37526
它的例子正好满足我的需求.哈哈.直接下载他给的链接,代码都不用敲了.
#define NO_WIN32_LEAN_AND_MEAN
#include <vcl.h>
#pragma hdrstop

#include <shellapi.h>
#include <shlobj.h>

#include "MainU.h"

#if (__BORLANDC__ >= 0x530)
#pragma package(smart_init)
#endif
#pragma resource "*.dfm"
TForm1 *Form1;

__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}

void __fastcall TForm1::FormCreate(TObject *Sender)
{
// Initialize OLE. This is required to get
// the cut and copy actions to work.
if (OleInitialize(0) != S_OK) {
ShowMessage("Unable to initialize OLE.");
return;
}
FileNameEdit->Text = Application->ExeName;
}

void __fastcall TForm1::FormDestroy(TObject *Sender)
{
// Unitialize OLE
OleUninitialize();
}

void __fastcall TForm1::GoBtnClick(TObject *Sender)
{
// Get an IShellFolder for the desktop.
LPSHELLFOLDER DesktopFolder;
SHGetDesktopFolder(&DesktopFolder);
if (!DesktopFolder) {
ShowMessage(
"Failed to get Desktop folder.");
return;
}

// Separate the file from the folder.
String FilePath = ExtractFilePath(
FileNameEdit->Text);
String FileName = ExtractFileName(
FileNameEdit->Text);

// Get a pidl for the folder the file
// is located in.
wchar_t Path[MAX_PATH];
LPITEMIDLIST ParentPidl;
DWORD Eaten;
StringToWideChar(FilePath, Path, MAX_PATH);
DWORD Result =
DesktopFolder->ParseDisplayName(
Handle, 0, Path, &Eaten, &ParentPidl, 0);
if (Result != NOERROR) {
ShowMessage("Invalid file name.");
return;
}

// Get an IShellFolder for the folder
// the file is located in.
LPSHELLFOLDER ParentFolder;
DesktopFolder->BindToObject(ParentPidl,
0, IID_IShellFolder, (void**)&ParentFolder);
if (!ParentFolder) {
ShowMessage("Invalid file name.");
return;
}

// Get a pidl for the file itself.
LPITEMIDLIST Pidl;
StringToWideChar(
FileName, Path, MAX_PATH);
ParentFolder->ParseDisplayName(
Handle, 0, Path, &Eaten, &Pidl, 0);

// Get the IContextMenu for the file.
LPCONTEXTMENU CM;
ParentFolder->GetUIObjectOf(
Handle, 1, (LPCITEMIDLIST*)&Pidl,
IID_IContextMenu, 0, (void**)&CM);

if (!CM) {
ShowMessage(
"Unable to get context menu interface.");
return;
}

// Set up a CMINVOKECOMMANDINFO structure.
CMINVOKECOMMANDINFO CI;
ZeroMemory(&CI, sizeof(CI));
CI.cbSize = sizeof(CMINVOKECOMMANDINFO);
CI.hwnd = Handle;

if (Sender == GoBtn) {
// Verbs that can be used are cut, paste,
// properties, delete, and so on.
String Action;
if (CutRb->Checked)
Action = "cut";
else if (CopyRb->Checked)
Action = "copy";
else if (DeleteRb->Checked)
Action = "delete";
else if (PropertiesRb->Checked)
Action = "properties";

CI.lpVerb = Action.c_str();
Result = CM->InvokeCommand(&CI);
if (Result)
ShowMessage(
"Error copying file to clipboard.");

// Clean up.
CM->Release();
ParentFolder->Release();
DesktopFolder->Release();
} else {
HMENU hMenu = CreatePopupMenu();
DWORD Flags = CMF_EXPLORE;
// Optionally the shell will show the extended
// context menu on some operating systems when
// the shift key is held down at the time the
// context menu is invoked. The following is
// commented out but you can uncommnent this
// line to show the extended context menu.
// Flags |= 0x00000080;
CM->QueryContextMenu(hMenu, 0, 1, 0x7FFF, Flags);

// Merge the form's popup menu with the shell
// menu.
MENUITEMINFO mi;
char buff[80];
// Work backwards, adding each item to the
// top of the shell context menu.
for (int i=PopupMenu1->Items->Count - 1;i>-1;i--) {
ZeroMemory(&mi, sizeof(mi));
mi.dwTypeData = buff;
mi.cch = sizeof(buff);
mi.cbSize = 44;
mi.fMask = MIIM_TYPE | MIIM_ID | MIIM_DATA;
// Get the menu item.
DWORD result = GetMenuItemInfo(
PopupMenu1->Handle, i, true, &mi);
if (result) {
// Modify its ID by adding 100 to the
// Command property. This ensures that
// there are no conflicts between the
// shell command IDs and the popup items.
mi.wID = PopupMenu1->Items->
Items[i]->Command + 100;
// Add the item to the shell menu.
InsertMenuItem(hMenu, 0, true, &mi);
}
}
// Show the menu.
TPoint pt;
GetCursorPos(&pt);
int Cmd = TrackPopupMenu(hMenu,
TPM_LEFTALIGN | TPM_LEFTBUTTON |
TPM_RIGHTBUTTON | TPM_RETURNCMD,
pt.x, pt.y, 0, Handle, 0);
// Handle the command. If the return value
// from TrackPopupMenu is less than 100 then
// a shell item was clicked.
if (Cmd < 100 && Cmd != 0) {
CI.lpVerb = MAKEINTRESOURCE(Cmd - 1);
CI.lpParameters = "";
CI.lpDirectory = "";
CI.nShow = SW_SHOWNORMAL;
CM->InvokeCommand(&CI);
}
// If Cmd is > 100 then it's one of our
// inserted menu items.
else
// Find the menu item.
for (int i=0;i<PopupMenu1->Items->Count;i++) {
TMenuItem* menu =
PopupMenu1->Items->Items[i];
// Call its OnClick handler.
if (menu->Command == Cmd - 100)
menu->OnClick(this);
}
// Release the memory allocated for the menu.
DestroyMenu(hMenu);
}
}

void __fastcall TForm1::Button2Click(TObject *Sender)
{
if (OpenDialog->Execute())
FileNameEdit->Text = OpenDialog->FileName;
}

void __fastcall TForm1::CloseBtnClick(TObject *Sender)
{
Close();
}

// The OnClick handlers for the poup menu.
void __fastcall TForm1::Hello1Click(TObject *Sender)
{
ShowMessage("Hello!");
}

void __fastcall TForm1::Test1Click(TObject *Sender)
{
ShowMessage("This is a test.");
}

fbmsyu 2009-01-19
  • 打赏
  • 举报
回复
对了,我不想用vcl.最好有个api.
popmenu需要我一条一条自己处理,太麻烦而且效率恐怕不高.
不知道谁有办法.
yumikoo 2009-01-19
  • 打赏
  • 举报
回复
控件全称是Tpopupmenu,使得他关联button
我知道你的意思,你是想走个捷径。
但是据我所知,捷径是理解各菜单项的消息。而且,标准控件里应该没有捷径可走,第三方控件里,个人也还没听说过。
fbmsyu 2009-01-19
  • 打赏
  • 举报
回复
楼上的,没说怎么显示这个menu1啊.我不想自己编辑菜单.最好从系统直接调用出来.
就像total commander ,你右键点击它列出的文件,它就会显示出系统的菜单了.

13,825

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder相关内容讨论区
社区管理员
  • 基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧