利用C++Builder自定义Windows窗体“系统菜单”
利用C++Builder自定義Windows窗體“系統(tǒng)菜單”
安徽合肥智能機(jī)械研究所張建軍
-------------------------------------------------------------------------------
??? 在開發(fā)Windows應(yīng)用程序時(shí),軟件人員希望所編制的程序具有風(fēng)格獨(dú)特的用戶界面,為此不惜采用一些占用系統(tǒng)內(nèi)存資源頗多的第三方OCX控件,結(jié)果導(dǎo)致程序運(yùn)行速度變慢或者打包后的安裝程序體積太大的缺點(diǎn)。其實(shí),如果我們仔細(xì)研究一下Windows提供的幾百個(gè)WinAPI,就不難發(fā)現(xiàn),通過直接調(diào)用API函數(shù),發(fā)送、接收或者攔截系統(tǒng)消息等方法,同樣可以實(shí)現(xiàn)在某些情況下只能依靠調(diào)用OCX才能達(dá)到的界面效果。
例如:為我們所熟知的屏幕抓圖軟件HyperSnap,在其強(qiáng)大的屏幕抓圖功能背后,還具有一項(xiàng)比較特殊的界面效果。
通常情況下,當(dāng)用鼠標(biāo)點(diǎn)擊一個(gè)Windows窗體左上角的Icon時(shí),所看到的系統(tǒng)菜單一般都是固定不變的。
??? HyperSnap的窗體改變了標(biāo)準(zhǔn)“系統(tǒng)菜單”,增加了多個(gè)新菜單項(xiàng),并分別賦予它們不同的功能。其實(shí)這種效果的實(shí)現(xiàn)并不復(fù)雜,主要通過調(diào)用GetSystemMenu、AppendMenu等API函數(shù)完成。下面,我們就以C++Builder為例,討論一下如何在自己的應(yīng)用程序中實(shí)現(xiàn)類似HyperSnap的界面效果,并給出完整代碼實(shí)例。
1.API函數(shù)介紹
??? ⑴ GetSystemMenu
① 功能:
允許訪問(拷貝或修改)系統(tǒng)菜單,普通Windows窗體如果未改變其菜單項(xiàng)狀態(tài),自動(dòng)采用標(biāo)準(zhǔn)Windows菜單,即“恢復(fù)”、“移動(dòng)”、“最大化”、“最小化”、“關(guān)閉”等。
②???? 原形:
HMENU GetSystemMenu(
??? HWND hWnd,?
??? BOOL bRevert???
?? );
③???? 入口參數(shù):
HWND為預(yù)改變系統(tǒng)菜單的窗體句柄。
bRevert為標(biāo)志。
當(dāng)bRevert為假,GetSystemMenu返回HWND代表窗體的拷貝,初始狀態(tài)下,拷貝與原窗體一致,但允許修改。
當(dāng)bRevert為真,GetSystemMenu將HWND代表的窗體菜單恢復(fù)默認(rèn)狀態(tài),之前對(duì)菜單的修改被取消。
④???? 返回值:
當(dāng)bRevert為假,返回HWND代表的窗體拷貝的句柄,當(dāng)bRevert為真,返
回值為Null。
???? ⑵ AppendMenu
??????? ①功能:
在指定菜單的最后插入一個(gè)菜單項(xiàng),并可規(guī)定該菜單項(xiàng)的文字內(nèi)容、外觀和觸發(fā)事件。
②???? 原形:
BOOL AppendMenu(
??? HMENU hMenu
??? UINT uFlags
??? UINT uIDNewItem
??? LPCTSTR lpNewItem
?? );??
③???? 入口參數(shù):
hMenu為欲增加菜單項(xiàng)的菜單句柄。
uFlags為新增菜單項(xiàng)的標(biāo)志,可以是幾種系統(tǒng)常量的組合。
UIDNewItem為新增菜單項(xiàng)的標(biāo)識(shí)。
lpNewItem為新增菜單項(xiàng)的文字內(nèi)容,可取MF_STRING、MF_SEPARATOR等值。
④???? 返回值:
成功返回0,失敗返回非0。
??? ⑶ WM_SYSCOMMAND
??????? 當(dāng)點(diǎn)擊菜單項(xiàng)時(shí)觸發(fā)的系統(tǒng)消息。
⒉ 編程實(shí)例
? ??⑴ 新建工程
在C++ Builder 5.0 IDE 中新建工程Project1,Project1中包含Form1。
??? ⑵ Form_Click事件
void __fastcall TForm1::FormClick(TObject *Sender)
{
? ChangeSystemMenu(Form1, "-", 0);
? ChangeSystemMenu(Form1, "自定義項(xiàng)目...", 99);
? Application->OnMessage = Form1->RegisterMsg;//指定窗體消息處理函數(shù)
}
??? ⑶ 自定義消息處理過程
void __fastcall TForm1::RegisterMsg(tagMSG &Msg, bool &Handled)
{
? if (Msg.message == WM_SYSCOMMAND)
??? if (Msg.wParam == 99)
????? ShowMessage("你點(diǎn)擊了自定義菜單");//自定義菜單響應(yīng)代碼
}
??? ⑷ 改變系統(tǒng)菜單過程
void __fastcall ChangeSystemMenu(TForm *Form, AnsiString Item, Word ItemID)
{
? void* NormalSystemMenu;
? void* MinSystemMenu;
? char* AItem = new char[255];
? PChar PItem;
? NormalSystemMenu = GetSystemMenu(Form->Handle, false);
? MinSystemMenu = GetSystemMenu(Application->Handle, false);
? if (Item == "-")
??? {
????? AppendMenu(NormalSystemMenu, MF_SEPARATOR, 0, 0);//增加菜單分隔線
????? AppendMenu(MinSystemMenu, MF_SEPARATOR, 0, 0);//增加菜單分隔線
??? }
? else
??? {
????? PItem = StrPCopy(AItem, Item);
????? AppendMenu(NormalSystemMenu, MF_STRING, ItemID, PItem);//增加菜單項(xiàng)文字
????? AppendMenu(MinSystemMenu, MF_STRING, ItemID, PItem);//增加菜單項(xiàng)文字
??? }
}
⒊ 實(shí)例代碼
? ?⑴ Unit1.h文件
//---------------------------------------------------------------------------
#ifndef unitAppendMenuH
#define unitAppendMenuH
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:??? // IDE-managed Components
? void __fastcall RegisterMsg(tagMSG &Msg, bool &Handled);//自定義菜單響應(yīng)事件
? void __fastcall FormClick(TObject *Sender);
private:??? // User declarations
public:???? // User declarations
? __fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
?⑵ Unit1.cpp文件
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "unitAppendMenu.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
? : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall ChangeSystemMenu(TForm *Form, AnsiString Item, Word ItemID)
{
? void* NormalSystemMenu;
? void* MinSystemMenu;
? char* AItem = new char[255];
? PChar PItem;
? NormalSystemMenu = GetSystemMenu(Form->Handle, false);
? MinSystemMenu = GetSystemMenu(Application->Handle, false);
? if (Item == "-")
??? {
????? AppendMenu(NormalSystemMenu, MF_SEPARATOR, 0, 0);//增加菜單分隔線
????? AppendMenu(MinSystemMenu, MF_SEPARATOR, 0, 0);//增加菜單分隔線
??? }
? else
??? {
????? PItem = StrPCopy(AItem, Item);
????? AppendMenu(NormalSystemMenu, MF_STRING, ItemID, PItem);//增加菜單項(xiàng)文字
????? AppendMenu(MinSystemMenu, MF_STRING, ItemID, PItem);//增加菜單項(xiàng)文字
??? }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::RegisterMsg(tagMSG &Msg, bool &Handled)
{
? if (Msg.message == WM_SYSCOMMAND)
??? if (Msg.wParam == 99)
????? ShowMessage("你點(diǎn)擊了自定義菜單");//自定義菜單響應(yīng)代碼
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormClick(TObject *Sender)
{
? ChangeSystemMenu(Form1, "-", 0);
? ChangeSystemMenu(Form1, "自定義項(xiàng)目...", 99);
? Application->OnMessage = Form1->RegisterMsg;//指定窗體消息處理函數(shù)
}
//---------------------------------------------------------------------------
??? 4.實(shí)例效果
??? 以上代碼在Win98、C++Builder 5.0環(huán)境下調(diào)試通過,所實(shí)現(xiàn)的界面效果如圖1所示。
| |
| |
圖1.本文代碼實(shí)現(xiàn)的自定義窗體“系統(tǒng)菜單”
------------------------------------------------------------------------------
總結(jié)
以上是生活随笔為你收集整理的利用C++Builder自定义Windows窗体“系统菜单”的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 利用生物视觉机制提高神经网络的对抗鲁棒性
- 下一篇: 用VC++实现console程序显示彩色