我想在我的应用程序中将“关于”菜单添加到标题栏的上下文菜单中。
我在互联网上进行了多次搜索,发现了这个很棒的主题如何自定义 Windows 窗体的系统菜单?但是没有针对视觉 C++ 的解决方案。我试图从提到的主题中调整解决方案,但出现了问题。我可以看到上下文菜单中出现了一些新内容,但没有“关于”项。
这是我的代码:
#pragma once
#include <string>
namespace context_menu {
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
using namespace System::Runtime::InteropServices;
using std::string;
// P/Invoke constants
const int WM_SYSCOMMAND = 0x112;
const int MF_STRING = 0x0;
const int MF_SEPARATOR = 0x800;
// P/Invoke declarations
[DllImport("user32.dll", CharSet = System::Runtime::InteropServices::CharSet::Auto, SetLastError = true)]
extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);
[DllImport("user32.dll", CharSet = System::Runtime::InteropServices::CharSet::Auto, SetLastError = true)]
extern bool AppendMenu(IntPtr hMenu, int uFlags, int uIDNewItem, string lpNewItem);
[DllImport("user32.dll", CharSet = System::Runtime::InteropServices::CharSet::Auto, SetLastError = true)]
extern bool InsertMenu(IntPtr hMenu, int uPosition, int uFlags, int uIDNewItem, string lpNewItem);
/// <summary>
/// Summary for Form1
///
/// WARNING: If you change the name of this class, you will need to change the
/// 'Resource File Name' property for the managed resource compiler tool
/// associated with all .resx files this class depends on. Otherwise,
/// the designers will not be able to interact properly with localized
/// resources associated with this form.
/// </summary>
public ref class Form1 : public System::Windows::Forms::Form
{
// ID for the About item on the system menu
private: static int SYSMENU_ABOUT_ID = 0x1;
public:
Form1(void)
{
InitializeComponent();
//
//TODO: Add the constructor code here
//
}
protected:
/// <summary>
/// Clean up any resources being used.
/// </summary>
~Form1()
{
if (components)
{
delete components;
}
}
private:
/// <summary>
/// Required designer variable.
/// </summary>
System::ComponentModel::Container ^components;
#pragma region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
void InitializeComponent(void)
{
this->SuspendLayout();
//
// Form1
//
this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
this->ClientSize = System::Drawing::Size(284, 261);
this->Name = L"Form1";
this->Text = L"Form1";
this->ResumeLayout(false);
}
#pragma endregion
protected: virtual System::Void OnHandleCreated( System::EventArgs^ e ) override {
System::Windows::Forms::Form::OnHandleCreated( e );
// Get a handle to a copy of this form's system (window) menu
IntPtr sysMenuHandle = GetSystemMenu( this->Handle, false );
// Add a separator
AppendMenu( sysMenuHandle, MF_SEPARATOR, 0, "" );
// Add the About menu item
AppendMenu( sysMenuHandle, MF_STRING, SYSMENU_ABOUT_ID, "&About…\n" );
}
protected: virtual System::Void WndProc( Message % m ) override {
System::Windows::Forms::Form::WndProc( m );
// Show test message
if( ( m.Msg == WM_SYSCOMMAND ) && ( (int)m.WParam == SYSMENU_ABOUT_ID ) )
{
MessageBox::Show( "Custom About Dialog" );
}
}
};
}
这是我的 结果。
编辑
根据@David Yaw 的回答,我添加#include <Windows.h>
并删除了所有不必要的代码。我需要解决一些小问题,过了一会儿它编译了。但随后出现了链接器错误:
1>context_menu.obj : error LNK2028: unresolved token (0A00001A) "extern "C" int __stdcall AppendMenuW(struct HMENU__ *,unsigned int,unsigned int,wchar_t const *)" (?AppendMenuW@@$$J216YGHPAUHMENU__@@IIPB_W@Z) referenced in function "protected: virtual void __clrcall context_menu::Form1::OnHandleCreated(class System::EventArgs ^)" (?OnHandleCreated@Form1@context_menu@@$$FM$AAMXP$AAVEventArgs@System@@@Z)
1>context_menu.obj : error LNK2028: unresolved token (0A00001B) "extern "C" struct HMENU__ * __stdcall GetSystemMenu(struct HWND__ *,int)" (?GetSystemMenu@@$$J18YGPAUHMENU__@@PAUHWND__@@H@Z) referenced in function "protected: virtual void __clrcall context_menu::Form1::OnHandleCreated(class System::EventArgs ^)" (?OnHandleCreated@Form1@context_menu@@$$FM$AAMXP$AAVEventArgs@System@@@Z)
1>context_menu.obj : error LNK2019: unresolved external symbol "extern "C" int __stdcall AppendMenuW(struct HMENU__ *,unsigned int,unsigned int,wchar_t const *)" (?AppendMenuW@@$$J216YGHPAUHMENU__@@IIPB_W@Z) referenced in function "protected: virtual void __clrcall context_menu::Form1::OnHandleCreated(class System::EventArgs ^)" (?OnHandleCreated@Form1@context_menu@@$$FM$AAMXP$AAVEventArgs@System@@@Z)
1>context_menu.obj : error LNK2019: unresolved external symbol "extern "C" struct HMENU__ * __stdcall GetSystemMenu(struct HWND__ *,int)" (?GetSystemMenu@@$$J18YGPAUHMENU__@@PAUHWND__@@H@Z) referenced in function "protected: virtual void __clrcall context_menu::Form1::OnHandleCreated(class System::EventArgs ^)" (?OnHandleCreated@Form1@context_menu@@$$FM$AAMXP$AAVEventArgs@System@@@Z)
所以现在怎么办?
代码:
#pragma once
#include <Windows.h>
#include <string>
namespace context_menu {
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
using namespace System::Runtime::InteropServices;
using std::string;
/// <summary>
/// Summary for Form1
///
/// WARNING: If you change the name of this class, you will need to change the
/// 'Resource File Name' property for the managed resource compiler tool
/// associated with all .resx files this class depends on. Otherwise,
/// the designers will not be able to interact properly with localized
/// resources associated with this form.
/// </summary>
public ref class Form1 : public System::Windows::Forms::Form
{
// ID for the About item on the system menu
private: static int SYSMENU_ABOUT_ID = 0x1;
public:
Form1(void)
{
InitializeComponent();
//
//TODO: Add the constructor code here
//
}
protected:
/// <summary>
/// Clean up any resources being used.
/// </summary>
~Form1()
{
if (components)
{
delete components;
}
}
private:
/// <summary>
/// Required designer variable.
/// </summary>
System::ComponentModel::Container ^components;
#pragma region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
void InitializeComponent(void)
{
this->SuspendLayout();
//
// Form1
//
this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
this->ClientSize = System::Drawing::Size(284, 261);
this->Name = L"Form1";
this->Text = L"Form1";
this->ResumeLayout(false);
}
#pragma endregion
protected: virtual System::Void OnHandleCreated( System::EventArgs^ e ) override {
// Basic function call
System::Windows::Forms::Form::OnHandleCreated( e );
// Pointer to this
HWND hWnd = static_cast<HWND>( this->Handle.ToPointer() );
// Get a handle to a copy of this form's system (window) menu
HMENU sysMenuHandle = GetSystemMenu( hWnd, false );
// Add a separator
AppendMenu( sysMenuHandle, MF_SEPARATOR, 0, L"" );
// Add the About menu item
AppendMenu( sysMenuHandle, MF_STRING, SYSMENU_ABOUT_ID, L"&About…\n" );
}
protected: virtual System::Void WndProc( Message % m ) override {
// Basic function call
System::Windows::Forms::Form::WndProc( m );
// komunikat
if( ( m.Msg == WM_SYSCOMMAND ) && ( (int)m.WParam == SYSMENU_ABOUT_ID ) )
{
MessageBox::Show( "Custom About Dialog" );
}
}
};
}