其他语言

本类阅读TOP10

·基于Solaris 开发环境的整体构思
·使用AutoMake轻松生成Makefile
·BCB数据库图像保存技术
·GNU中的Makefile
·射频芯片nRF401天线设计的分析
·iframe 的自适应高度
·BCB之Socket通信
·软件企业如何实施CMM
·入门系列--OpenGL最简单的入门
·WIN95中日志钩子(JournalRecord Hook)的使用

分类导航
VC语言Delphi
VB语言ASP
PerlJava
Script数据库
其他语言游戏开发
文件格式网站制作
软件工程.NET开发
利用C++Builder自定义Windows窗体“系统菜单”

作者:未知 来源:月光软件站 加入时间:2005-2-28 月光软件站

利用C++Builder自定义Windows窗体“系统菜单”

 

安徽合肥智能机械研究所张建军

-------------------------------------------------------------------------------

    在开发Windows应用程序时,软件人员希望所编制的程序具有风格独特的用户界面,为此不惜采用一些占用系统内存资源颇多的第三方OCX控件,结果导致程序运行速度变慢或者打包后的安装程序体积太大的缺点。其实,如果我们仔细研究一下Windows提供的几百个WinAPI,就不难发现,通过直接调用API函数,发送、接收或者拦截系统消息等方法,同样可以实现在某些情况下只能依靠调用OCX才能达到的界面效果。

例如:为我们所熟知的屏幕抓图软件HyperSnap,在其强大的屏幕抓图功能背后,还具有一项比较特殊的界面效果。

通常情况下,当用鼠标点击一个Windows窗体左上角的Icon时,所看到的系统菜单一般都是固定不变的。

    HyperSnap的窗体改变了标准“系统菜单”,增加了多个新菜单项,并分别赋予它们不同的功能。其实这种效果的实现并不复杂,主要通过调用GetSystemMenuAppendMenuAPI函数完成。下面,我们就以C++Builder为例,讨论一下如何在自己的应用程序中实现类似HyperSnap的界面效果,并给出完整代码实例。

1API函数介绍

    ⑴ GetSystemMenu

① 功能:

允许访问(拷贝或修改)系统菜单,普通Windows窗体如果未改变其菜单项状态,自动采用标准Windows菜单,即“恢复”、“移动”、“最大化”、“最小化”、“关闭”等。

     原形:

HMENU GetSystemMenu(

    HWND hWnd, 

    BOOL bRevert   

   );

     入口参数:

HWND为预改变系统菜单的窗体句柄。

bRevert为标志。

bRevert为假,GetSystemMenu返回HWND代表窗体的拷贝,初始状态下,拷贝与原窗体一致,但允许修改。

bRevert为真,GetSystemMenuHWND代表的窗体菜单恢复默认状态,之前对菜单的修改被取消。

     返回值:

bRevert为假,返回HWND代表的窗体拷贝的句柄,当bRevert为真,返

回值为Null

     AppendMenu

        ①功能:

在指定菜单的最后插入一个菜单项,并可规定该菜单项的文字内容、外观和触发事件。

     原形:

BOOL AppendMenu(

    HMENU hMenu

    UINT uFlags

    UINT uIDNewItem

    LPCTSTR lpNewItem

   );  

     入口参数:

hMenu为欲增加菜单项的菜单句柄。

uFlags为新增菜单项的标志,可以是几种系统常量的组合。

UIDNewItem为新增菜单项的标识。

lpNewItem为新增菜单项的文字内容,可取MF_STRINGMF_SEPARATOR等值。

     返回值:

成功返回0,失败返回非0

    WM_SYSCOMMAND

        当点击菜单项时触发的系统消息。

编程实例

    ⑴ 新建工程

C++ Builder 5.0 IDE 中新建工程Project1Project1中包含Form1

    Form_Click事件

void __fastcall TForm1::FormClick(TObject *Sender)

{

  ChangeSystemMenu(Form1, "-", 0);

  ChangeSystemMenu(Form1, "自定义项目...", 99);

  Application->OnMessage = Form1->RegisterMsg;//指定窗体消息处理函数

}

    ⑶ 自定义消息处理过程

void __fastcall TForm1::RegisterMsg(tagMSG &Msg, bool &Handled)

{

  if (Msg.message == WM_SYSCOMMAND)

    if (Msg.wParam == 99)

      ShowMessage("你点击了自定义菜单");//自定义菜单响应代码

}

    ⑷ 改变系统菜单过程

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);//增加菜单项文字

      AppendMenu(MinSystemMenu, MF_STRING, ItemID, PItem);//增加菜单项文字

    }

}

实例代码

   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);//自定义菜单响应事件

  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);//增加菜单项文字

      AppendMenu(MinSystemMenu, MF_STRING, ItemID, PItem);//增加菜单项文字

    }

}

//---------------------------------------------------------------------------

void __fastcall TForm1::RegisterMsg(tagMSG &Msg, bool &Handled)

{

  if (Msg.message == WM_SYSCOMMAND)

    if (Msg.wParam == 99)

      ShowMessage("你点击了自定义菜单");//自定义菜单响应代码

}

//---------------------------------------------------------------------------

void __fastcall TForm1::FormClick(TObject *Sender)

{

  ChangeSystemMenu(Form1, "-", 0);

  ChangeSystemMenu(Form1, "自定义项目...", 99);

  Application->OnMessage = Form1->RegisterMsg;//指定窗体消息处理函数

}

//---------------------------------------------------------------------------

    4.实例效果

    以上代码在Win98C++Builder 5.0环境下调试通过,所实现的界面效果如图1所示。

 

 

 


 


1.本文代码实现的自定义窗体“系统菜单”

------------------------------------------------------------------------------




相关文章

相关软件