vc (dword)wparam== vc dword
发布日期:2020-07-30摘要:VC++的SendMessage函数如何利用wParam lParam传递参数 理论上在使用自定义消息时,WPARAM、LPARAM的含义可以程序员任意指定的,但是最好遵从MFC中的习惯。在调用Se...
VC++的SendMessage函数如何利用wParam lParam传递参数
理论上在使用自定义消息时,WPARAM、LPARAM的含义可以程序员任意指定的,但是最好遵从MFC中的习惯。
在调用SendMessage()函数时,第二个参数是WPARAM,第三个参数是这个消息的LPARAM,但是你在程序中某个类中写下ON_MESSAGE()宏来处理这个消息时,处理函数SomeHandler(WPARAM,LPRAM(默认是0))中解释这两个参数时必须按照SendMessage调用中的意义来进行。
SendMessage的基本结构如下: SendMessage( HWND hWnd, //消息传递的目标窗口或线程的句柄。
UINT Msg, //消息类别(这里可以是一些系统消息,也可以是自己定义,下文具体介绍,) WPARAM wParam, //参数1 (WPARAM 其实是与UINT是同种类型的, //在vc编译器中右键有个“转到WPARAM的定义”的选项可以查看。
LPARAM lParam); //参数2 例如:::SendMessage(this->m_hWnd,WM_MY_DOSOME, (WPARAM) 0, (LPARAM) 0); SendMessage及WPRAME、LPARAME typedef unsigned int UINT typedef UINT WPARAM typedef LONG LPARAM typedef LONG LRESULT MFC中的SendMessage()则是,谁调用它,则其就是接收消息的载体,必须实现消息。
例如:pView->SendMessage(),则有pView窗口接收消息(视也是一个窗口)。
消息响应机制 1、消息的组成:一个消息由一个消息名称(UINT),和两个参数(WPARAM,LPARAM)组成。
当用户进行了输入或是窗口的状态发生改变时系统都会发送消息到某一个窗口。
例如当菜单选中之后会有WM_COMMAND消息发送,WPARAM的低字中(LOWORD(wParam))是命令的ID号,对菜单来讲就是菜单ID。
当然用户也可以定义自己的消息名称,也可以利用自定义消息来发送通知和传送数据。
2、谁将收到消息:一个消息必须由一个窗口接收。
在窗口的过程(WNDPROC)中可以对消息进行分析,对自己感兴趣的消息进行处理。
例如你希望对菜单选择进行处理那么你可以定义对WM_COMMAND进行处理的代码,如果希望在窗口中进行图形输出就必须对WM_PAINT进行处理。
3、未处理的消息到那里去了:MS为窗口编写了默认的窗口过程,这个窗口过程将负责处理那些你不处理消息。
正因为有了这个默认窗口过程我们才可以利用Windows的窗口进行开发而不必过多关注窗口各种消息的处理。
例如窗口在被拖动时会有很多消息发送,而我们都可以不予理睬让系统自己去处理。
4、窗口句柄:说到消息就不能不说窗口句柄,系统通过窗口句柄来在整个系统中唯一标识一个窗口,发送一个消息时必须指定一个窗口句柄表明该消息由那个窗口接收。
而每个窗口都会有自己的窗口过程,所以用户的输入就会被正确的处理。
例如有两个窗口共用一个窗口过程代码,你在窗口一上按下鼠标时消息就会通过窗口一的句柄被发送到窗口一而不是窗口二。
消息机制: 系统将会维护一个或多个消息队列,所有产生的消息都回被放入或是插入队列中。
系统会在队列中取出每一条消息,根据消息的接收句柄而将该消息发送给拥有该窗口的程序的消息循环。
每一个运行的程序都有自己的消息循环,在循环中得到属于自己的消息并根据接收窗口的句柄调用相应的窗口过程。
而在没有消息时消息循环就将控制权交给系统所以Windows可以同时进行多个任务。
MFC中SendMessage的用法与相应函数的添: 1、::SendMessage(AfxGetMainWnd()->m_hWnd,WM_CHILDFRAMEDBCLK ,0,0); 其中WM_CHILDFRAMEDBCLK是自定义的消息ID(其ID为WM_USER+1),AfxGetMainWnd()->m_hWnd是获得主窗口(这里不能使用GetParent()->m_hWnd或者GetParentFrame()->m_hWnd,因为这是获得父窗口,但父窗口不一定是主窗口,一定要注意,不然消息就会发错导致接收不到。
2、然后接下来定义一个消息需要映射的函数,如下: afx_msg LRESULT OnChlidFrameDBClick(WPARAM wParam, LPARAMlParam); 注意格式必须是:两个参数必不可少,返回类型一定为LRESULT,网上很多文章都忽略了这两点,这也是网上文章普遍错误的地方。
3、添加消息函数映射 ON_MESSAGE(WM_CHILDFRAMEDBCLK,OnChlidFrameDBClick) 注意这里必须是ON_MESSAGE, 不能使用ON_COMMAND, 前者主要针对用户自定义消息,后者针对WM_COMMAND命令,比如菜单、工具栏等. 4、实现消息函数: 我们在接收窗体里定义一个这样的事情(过程), LRESULTCMainFrame::OnChlidFrameDBClick(WPARAM wParam, LPARAM lParam) { CancelFullScreenWin(); // 这里调用了一个使子窗口全屏的自写函数,我就不贴出来了,以后专题将的时候会提到 return 0; }
vc中如何获取WM
(一) 原理 1、最小化的原理:首先要将窗口隐藏,然后 在右下角绘制图标。
2、恢复的原理:将窗口显示,再将托盘中的图片删除。
(二)程序实现 1、自定义消息WM_SHOWTASK: #define WM_SHOWTASK (WM_USER +1) 2、在MFC的::OnSysCommand(UINT nID, LPARAM lParam)函数体中增加一个命令响应 if(nID==SC_MINIMIZE) ToTray(); //最小化到托盘的函数 3、在消息映射中添加 ON_MESSAGE(WM_SHOWTASK,OnShowTask),其中WM_SHOWTASK是消息名, OnShowTask是自己定义的消息响应函数,后面有说明。
(三)具体函数内容 1、最小化到托盘函数 void CMyDlg::ToTray(){ NOTIFYICONDATA nid; nid.cbSize=(DWORD)sizeof(NOTIFYICONDATA); nid.hWnd=this->m_hWnd; nid.uID=IDR_MAINFRAME; nid.uFlags=NIF_ICON|NIF_MESSAGE|NIF_TIP ; nid.uCallbackMessage=WM_SHOWTASK;//自定义的消息名称 nid.hIcon=LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDR_MAINFRAME)); strcpy(nid.szTip,"程序名称"); //信息提示条 Shell_NotifyIcon(NIM_ADD,&nid); //在托盘区添加图标 ShowWindow(SW_HIDE); //隐藏主窗口} 2、恢复界面函数 在头文件中定义消息响应函数afx_msg LRESULT OnShowTask(WPARAM wParam,LPARAM lParam) ; //wParam接收的是图标的ID,而lParam接收的是鼠标的行为 LRESULT CMyDlg::OnShowTask(WPARAM wParam,LPARAM lParam) { if(wParam!=IDR_MAINFRAME) return 1; switch(lParam) { case WM_RBUTTONUP://右键起来时弹出快捷菜单,这里只有一个“关闭” { LPPOINT lpoint=new tagPOINT; ::GetCursorPos(lpoint);//得到鼠标位置 CMenu menu; menu.CreatePopupMenu();//声明一个弹出式菜单 //增加菜单项“关闭”,点击则发送消息WM_DESTROY给主窗口(已 //隐藏),将程序结束。
menu.AppendMenu(MF_STRING,WM_DESTROY,"关闭"); //确定弹出式菜单的位置 menu.TrackPopupMenu(TPM_LEFTALIGN,lpoint->x,lpoint->y,this); //资源回收 HMENU hmenu=menu.Detach(); menu.DestroyMenu(); delete lpoint; } break; case WM_LBUTTONDBLCLK://双击左键的处理 { this->ShowWindow(SW_SHOW);//简单的显示主窗口完事儿 DeleteTray(); } break; default: break; } return 0; } 3、删除托盘图标函数 void CMyDlg::DeleteTray(){ NOTIFYICONDATA nid; nid.cbSize=(DWORD)sizeof(NOTIFYICONDATA); nid.hWnd=this->m_hWnd; nid.uID=IDR_MAINFRAME; nid.uFlags=NIF_ICON|NIF_MESSAGE|NIF_TIP ; nid.uCallbackMessage=WM_SHOWTASK;//自定义的消息名称 nid.hIcon=LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDR_MAINFRAME)); strcpy(nid.szTip,"程序名称"); //信息提示条为“计划任务提醒” Shell_NotifyIcon(NIM_DELETE,&nid); //在托盘区删除图标 }
VC线程函数的返回值有什么用?
一个线程一般用来完成一个任务。
线程一般用不同的返回值来表示任务的完成情况,最常见的是用0和1来表示成功与失败,有时候会用更多的数来表示更多的含义。
创建这个线程的那个主线程往往通过GetExitCodeThread函数取得分线程的这个返回值来了解分线程任务的完成情况。
键盘钩子怎么 使用
I:设置钩子 设置钩子是通过SetWindowsHookEx ()的API函数.原形: HHOOK SetWindowsHookEx(int idHook,HOOKPROC lpfn,HINSTANCE hMod,DWORD dwThreadId) idhook:装入钩子的类型.lpfn: 钩子进程的入口地址 hMod: 应用程序的事件句柄 dwThreadId: 装入钩子的线程标示 参数:idHook:这个参数可以是以下值:WH_CALLWNDPROC、WH_CALLWNDPROCRET、WH_CBT、WH_DEBUG、WH_FOREGROUNDIDLE、WH_GETMESSAGE、WH_JOURNALPLAYBACK、WH_JOURNALRECORD、WH_KEYBOARD、WH_KEYBOARD_LL、WH_MOUSE、WH_MOUSE_LL、WH_MSGFILTER、WH_SHELL、WH_SYSMSGFILTER。
对于这些参数,我不想一一加以解释,因为MSDN中有关于他们的详细注解。
我只挑选其中的几个加以中文说明。
WH_KEYBOARD:一旦有键盘敲打消息(键盘的按下、键盘的弹起),在这个消息被放在应用程序的消息队列前,WINDOWS将会调用你的钩子函数。
钩子函数可以改变和丢弃键盘敲打消息。
WH_MOUSE:每个鼠标消息在被放在应用程序的消息队列前,WINDOWS将会调用你的钩子函数。
钩子函数可以改变和丢弃鼠标消息。
WH_GETMESSAGE:每次当你的应用程序调用一个GetMessage()或者一个PeekMessage()为了去从应用程序的消息队列中要求一个消息时,WINDOWS都会调用你的钩子函数。
而钩子函数可以改变和丢弃这个消息。
II:释放钩子 钩子的释放使用的是UnhookWindowsHookEx()函数 原形:BOOL UnhookWindowsHookEx( HHOOK hhk ) UnhookWindowsHookEx()函数将释放的是钩子链中函数SetWindowsHookEx所装入的钩子进程。
hhk: 将要释放的钩子进程的句柄。
III:钩子进程 钩子进程使用函数HookProc;其实HookProc仅仅只是应用程序定义的符号。
比如你可以写成KeyBoardHook.但是参数是不变的。
Win32 API提供了诸如:CallWndProc、GetMsgProc、DebugProc、CBTProc、MouseProc、KeyboardProc、MessageProc等函数,对于他们的详细讲解,可以看MSDN我在此只讲解一下KeyBoardHook的含义。
原形:LRESULT CALLBACK KeyBoardHook (int nCode, WPARAM wParam, LPARAM lParam) 说明:钩子进程是一些依附在一个钩子上的一些函数,因此钩子进程只被WINDOWS调用而不被应用程序调用,他们有时就需要作为一个回调函数(CALLBACK)。
参数说明:nCode:钩子代码,钩子进程使用钩子代码去决定是否执行。
而钩子代码的值是依靠钩子的种类来定的。
每种钩子种类都有他们自己一系列特性的代码。
比如对于WH_KEYBOARD,钩子代码的参数有:HC_ACTION,HC_NOREMOVE。
HC_ACTION的意义:参数wParam 和lParam 包含了键盘敲打消息的信息,HC_NOREMOVE的意义:参数wParam 和lParam包含了键盘敲打消息的信息,并且,键盘敲打消息一直没有从消息队列中删除。
(应用程序调用PeekMessage函数,并且设置PM_NOREMOVE标志)。
也就是说当nCode等于HC_ACTION时,钩子进程必须处理消息。
而为HC_NOREMOVE时,钩子进程必须传递消息给CallNextHookEx函数,而不能做进一步的处理,而且必须有CallNextHookEx函数的返回值。
wParam:键盘敲打所产生的键盘消息,键盘按键的虚拟代码。
lParam:包含了消息细节。
注意:如果钩子进程中nCode小于零,钩子进程必须返回(return) CallNextHookEx(nCode,wParam,lParam);而钩子进程中的nCode大于零,但是钩子进程并不处理消息,作者推荐你调用CallNextHookEx并且返回该函数的返回值。
否则,如果另一个应用程序也装入WH_KEYBOARD 钩子,那么该钩子将不接受钩子通知并且返回一个不正确的值。
如果钩子进程处理了消息,它可能返回一个非零值去阻止系统传递该信息到其它剩下的钩子或者windows进程。
所以最好在钩子进程的最后都返回CallNextHookEx的返回值。
IV:调用下一个钩子函数 调用下一个钩子函数时使用CallNexHookEx函数。
原形:LRESULT CallNextHookEx( HHOOK hhk, int nCode, WPARAM wParam, LPARAM lParam ) CallNexHookEx()函数用于对当前钩子链中的下一个钩子进程传递钩子信息,一个钩子进程既可以在钩子信息处理前,也可以在钩子信息处理后调用该函数。
为什么使用该函数已在iii钩子进程中的“注意”中,加以了详细的说明。
hhk: 当前钩子的句柄 nCode: 传送到钩子进程的钩子代码。
wParam:传送到钩子进程的值。
lParam:传送到钩子进程的值。
参数:hhk: 当前钩子的句柄. 应用程序接受这个句柄,作为先前调用SetWindowsHookE函数的结果 nCode: 传送到钩子进程的钩子代码,下一个钩子进程使用这个代码以此决定如何处理钩子信息 wParam:传送给钩子进程的wParam 参数值 ,参数值的具体含义与当前钩子链的挂接的钩子类型有关 lParam : 传送给钩子进程的wParam 参数值 ,参数值的具体含义与当前钩子链的挂接的钩子类型有关 返回值:返回值是链中下一个钩子进程返回的值,当前钩子进程必须返...
在VC状态下如何编程求2至1000之间的完数?
打开VC++6.0,点击工具栏上的“新建”图标建立一个空白文档(注意不是点击菜单File—New),把以下代码复制进去:#include #include void main(){int m,i,s=0;printf("2~1000的数中:\n");for(m=2;m{for (i=1;i{ if(m%i==0)s=s+i;}if(s==m){printf("%d为一个完数,因子为",m);for(i=1;i{ if(m%i==0)printf("%d,",i);}printf("\n");}s=0;}} 点击“编译”,弹出的对话框选择“是”(将为你自动建立一个工程),将文件名改为“Text1.c”,选择一个工程的存放位置,点击“保存”。
然后编译运行即可。
不知道你还有没有特殊要求,比如想要基于MFC而不仅仅是基于VC环境?
急!VC6.0怎样把字符串转换成数据?
C库有标准函数atoi(将字符串转换成整型数) 相关函数 atof,atol,atrtod,strtol,strtoul表头文件 #include定义函数 int atoi(const char *nptr);函数说明 atoi()会扫描参数nptr字符串,跳过前面的空格字符,直到遇上数字或正负符号才开始做转换,而再遇到非数字或字符串结束时("\0")才结束转换,并将结果返回。
返回值 返回转换后的整型数。
附加说明 atoi()与使用strtol(nptr,(char**)NULL,10);结果相同。
范例 /* 将字符串a 与字符串b转换成数字后相加*/#includemian(){char a[]=”-100”;char b[]=”456”;int c;c=atoi(a)+atoi(b);printf(c=%d\n”,c);}执行 c=356
vc++编程怎么知道键值??着急!!
MSG中的wParam键盘常用ASCII码 ESC键 VK_ESCAPE (27)回车键: VK_RETURN (13)TAB键: VK_TAB (9)Caps Lock键: VK_CAPITAL (20)Shift键: VK_SHIFT ()Ctrl键: VK_CONTROL (17)Alt键: VK_MENU (18)空格键: VK_SPACE (/32)退格键: VK_BACK (8)左徽标键: VK_LWIN (91)右徽标键: VK_LWIN (92)鼠标右键快捷键:VK_APPS (93) Insert键: VK_INSERT (45)Home键: VK_HOME (36)Page Up: VK_PRIOR (33)PageDown: VK_NEXT (34)End键: VK_END (35)Delete键: VK_DELETE (46)方向键(←): VK_LEFT (37)方向键(↑): VK_UP (38)方向键(→): VK_RIGHT (39)方向键(↓): VK_DOWN (40)F1键: VK_F1 (112)F2键: VK_F2 (113)F3键: VK_F3 (114)F4键: VK_F4 (115)F5键: VK_F5 (116)F6键: VK_F6 (117)F7键: VK_F7 (118)F8键: VK_F8 (119)F9键: VK_F9 (120)F10键: VK_F10 (121)F11键: VK_F11 (122)F12键: VK_F12 (123)Num Lock键: VK_NUMLOCK (144)小键盘0: VK_NUMPAD0 (96)小键盘1: VK_NUMPAD0 (97)小键盘2: VK_NUMPAD0 (98)小键盘3: VK_NUMPAD0 (99)小键盘4: VK_NUMPAD0 (100)小键盘5: VK_NUMPAD0 (101)小键盘6: VK_NUMPAD0 (102)小键盘7: VK_NUMPAD0 (103)小键盘8: VK_NUMPAD0 (104)小键盘9: VK_NUMPAD0 (105)小键盘.: VK_DECIMAL (110)小键盘*: VK_MULTIPLY (106)小键盘+: VK_MULTIPLY (107)小键盘-: VK_SUBTRACT (109)小键盘/: VK_DIVIDE (111)Pause Break键: VK_PAUSE (19)Scroll Lock键: VK_SCROLL (145)
那些漂亮的程序界面特效是VC做的?比如进度条之类的。
1、 启动Visual C++6.0,生成一个单文档应用程序prgsbar,项目的视图类的基类选择CEdit类; 2、 在程序的Resource.h文件中添加自定义消息的定义:#define MYWM_PROGRESS (WM_USER+1) 3、 在程序的主框架窗口CMainFrame类的头文件中声明MYWM_PROGRESS的消息响应函数afx_msg LRESULT OnProgress(WPARAM wp, LPARAM lp),在该类的实现中添加消息映射ON_MESSAGE(MYWM_PROGRESS,OnProgress); 4、 将CMainFrame类中的工具条对象改为CProgStatusBar m_wndStatusBar; 5、 重载CPrgsbarDoc::Serialize(CArchive& ar)函数,用来处理读取文件时的进度条仿真; 6、 添加代码,编译运行程序。
程序代码////////////////////////////////////////////CprogStatusBar类的头文件;// Status bar with progress control.class CProgStatusBar : public CStatusBar { public: CProgStatusBar(); virtual ~CProgStatusBar(); CProgressCtrl& GetProgressCtrl() { return m_wndProgBar; } void OnProgress(UINT pct); protected: CProgressCtrl m_wndProgBar; // the progress bar afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); afx_msg void OnSize(UINT nType, int cx, int cy); DECLARE_MESSAGE_MAP() DECLARE_DYNAMIC(CProgStatusBar) };///////////////////////////////////////////////////////////////////////////// CprogStatusBar类的实现文件;#include "StdAfx.h"#include "ProgBar.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILE static char THIS_FILE[] = __FILE__;#endif IMPLEMENT_DYNAMIC(CProgStatusBar, CStatusBar) BEGIN_MESSAGE_MAP(CProgStatusBar, CStatusBar) ON_WM_CREATE() ON_WM_SIZE() END_MESSAGE_MAP()//////////////////////////////////////////////////////////////// CProgStatusBar::CProgStatusBar() {} CProgStatusBar::~CProgStatusBar() {}////////////////////////////////////////创建状态条时也创建进程条 int CProgStatusBar::OnCreate(LPCREATESTRUCT lpcs) { lpcs->style |= WS_CLIPCHILDREN; VERIFY(CStatusBar::OnCreate(lpcs)==0); VERIFY(m_wndProgBar.Create(WS_CHILD, CRect(), this, 1)); m_wndProgBar.SetRange(0,100); //设置进程条的范围; return 0; }////////////////////////////////////////////////////使进程度条的尺寸与状态条的尺寸同步变化;void CProgStatusBar::OnSize(UINT nType, int cx, int cy) { CStatusBar::OnSize(nType, cx, cy); CRect rc; GetItemRect(0, &rc); m_wndProgBar.MoveWindow(&rc,FALSE); }////////////////////////////////////////////////////////////根据pct的当前值对进程条进行设置 void CProgStatusBar::OnProgress(UINT pct) { CProgressCtrl& pc = m_wndProgBar; DWORD dwOldStyle = pc.GetStyle(); DWORD dwNewStyle = dwOldStyle; if (pct>0) //如果pct>0,将显示进度条 dwNewStyle |= WS_VISIBLE; else //否则隐藏进度条; dwNewStyle &= ~WS_VISIBLE; if (dwNewStyle != dwOldStyle) { SetWindowText(NULL); //显示进度条前清空状态条; SetWindowLong(pc.m_hWnd, GWL_STYLE, dwNewStyle); //设置进度条处于显示状态; } // 设置进度条的当前位置; pc.SetPos(pct); if (pct==0) // 如果pct等于0,通知主框架窗口显示空闲信息; GetParent()->PostMessage(WM_SETMESSAGESTRING, AFX_IDS_IDLEMESSAGE); } /////////////////////////////////////////////////////////////////////////文档装载处理函数; void CPrgsbarDoc::Serialize(CArchive& ar) { CWnd* pFrame = AfxGetMainWnd(); if (!ar.IsStoring()) { for (int pct=10; pct Sleep(150); if (pFrame) pFrame->SendMessage(MYWM_PROGRESS, pct); } } if (pFrame) pFrame->SendMessage(MYWM_PROGRESS, 0); ((CEditView*)m_viewList.GetHead())->SerializeRaw(ar);//显示文本文件的内容;}
VC C++ API 模拟自动点击
楼上的回答很正确,在执行MessageBox函数之后,程序会一直等待你选择后才执行后面的代码。
试试使用多线程来实现,一个主线程弹出一个消息框,一个线程点击确定。
试试:#include DWORD WINAPI ThreadFunc( LPVOID lpParam ) { HWND hwnd1,hwnd2;while(1){ Sleep(3000); // 每隔3秒去查看是否还有要点击的hwnd1=::FindWindow(NULL,"1");if (hwnd1 != NULL){hwnd2=::FindWindowEx(hwnd1,NULL,NULL,"是(&Y)");::PostMessage(hwnd2,WM_LBUTTONDOWN,MK_LBUTTON,MAKELPARAM(0,0));::PostMessage(hwnd2,WM_LBUTTONUP,MK_LBUTTON,MAKELPARAM(0,0));}}return 0;} int main(int argc, char *argv[]){::CreateThread(NULL, 0, ThreadFunc, NULL, 0, NULL); // 创建点击确定的线程::MessageBox(NULL,"1","1",MB_YESNO);return 0;}
求助:怎么样才能用vc的win32应用程序或者是控制台程序实现托盘图...
打开一个新工程,将工程文件取名为test、单元文件取名为main。
在窗口上放置二个按钮、一个标签,其属性按如下设置 组件 属性 值 Label1 Caption 按OK按钮...终止程序 OKButton Caption &OKButton CancelButton Caption &CancelButton 打开文件main.h,加入斜体部分声明(以手工输入部分均以斜体表示,以下同) class TForm1 : public TForm { __published: // IDE-managed Components TButton *OKButton; TButton *CancelButton; TLabel *Label1; void __fastcall FormCreate(TObject *Sender); void __fastcall FormDestroy(TObject *Sender); void __fastcall OKButtonClick(TObject *Sender); void __fastcall CancelButtonClick(TObject *Sender); private: // User declarations unsigned ugIconMessage; void AddTray(); void DeleteTray(); protected:virtual void __fastcall WndProc(Messages::TMessage &Message); public: // User declarations __fastcall TForm1(TComponent* Owner); }; 切换到main.cpp,加入以下函数及声明 #include#pragma hdrstop#include#include "main.h"//---------------------------------------------------------------------------#pragma package(smart_init)#pragma resource "*.dfm" TForm1 *Form1;//--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner): TForm(Owner) { }//--------------------------------------------------------------------------- void TForm1::AddTray()//创建任务栏布告区图标 { NOTIFYICONDATA icondata;① memset(&icondata,0,sizeof(icondata));② icondata.cbSize=sizeof(icondata); icondata.hWnd=Handle;③ strncpy(icondata.szTip,"我的任务",sizeof(icondata.szTip));④ Application->Icon->LoadFromFile("e:\\yxg\\map\\system\\ico\\yxg.ico"); icondata.hIcon=Application->Icon->Handle; ⑤ icondata.uCallbackMessage=ugIconMessage;⑥ icondata.uFlags=NIF_MESSAGE|NIF_ICON|NIF_TIP;⑦ Shell_NotifyIcon(NIM_ADD,&icondata);⑧ } void TForm1::DeleteTray()//删除任务栏布告区图标 { NOTIFYICONDATA icondata; memset(&icondata,0,sizeof(icondata)); icondata.cbSize=sizeof(icondata); icondata.hWnd=Handle; Shell_NotifyIcon(NIM_DELETE,&icondata); ⑧ } void __fastcall TForm1::WndProc(Messages::TMessage &Message) { if(Message.Msg==ugIconMessage)//如果产生的是与该图标相关的消息 { if(Message.LParam==WM_LBUTTONDBLCLK) Application->Terminate();⑨ if(Message.LParam==WM_RBUTTONDBLCLK) { ShowWindow(Application->Handle,SW_SHOW);// Application->ShowMainForm=true; Form1->Visible=true; ⑩ } return; } TForm::WndProc(Message); } ①申请一个任务栏布告区图标的结构变量;②将结构变量的内容清零;③取得当前窗口的句柄;④输入鼠标经过该图标时的提示字符串;⑤将自已所喜爱的图标文件作为任务栏布告区的图标;⑥取得回调信息变量;⑦当结构变量中成员hIcon、uCallbackMessage与szTip 出错时将给出错误标志;⑧调用函数Shell_NotifyIcon()在任务栏布告区产生或删除一个图标;⑨当鼠标左键在该图标处双击时,终止程序运行;⑩当鼠标右键在该图标处双击时,显示与该图标相关的应用程序。
我们知道,所有的TWinControl派生来的VCL类都有一个WndProc函数,调用这个函数可以发送消息并被相关的窗口接收,WndProc被定义成一个虚函数,这样一个派生类就可以定义它自已的WndProc函数来代替其父类的WndProc函数。
在这里,与任务栏布告区图标相关的消息由子类的WndProc函数处理,否则调用父类的WndProc处理。
在Form1的OnCreate事件中加入以下代码: void __fastcall TForm1::FormCreate(TObject *Sender) { ugIconMessage=RegisterWindowMessage("IconNotify");① AddTray();② Form1->Visible=false;③ } ①调用RegisterWindowMessage()函数来创建一个独一无二的消息编号,以确保没有冲突;②在任务栏布告区创建图标;③显示窗体; 在Form1的OnDestroy事件中加入DeleteTray()函数以删除图标。
将OKButton与CancelButton按钮的OnClick事件增加代码以隐藏主窗口及终止程序运行。
void __fastcall TForm1::OKButtonClick(TObject *Sender) { Form1->Visible=false; ShowWindow(Application->Handle,SW_HIDE); Application->ShowMainForm=false; }//--------------------------------------------------------------------------- void __fastcall TForm1::CancelButtonClick(TObject *Sender) { Application->Terminate(); } 最后,在WinMain函数中增加两行代码以便程序在开始运行时就隐藏主窗体。
WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) { try { Application->Initialize(); Application->CreateForm(__classid(TForm1), &Form1); ShowWindow(Application->Handle,SW_HIDE); Application->ShowMainForm=false; Application->Run(); } catch (Exception &exception) { Application->ShowException(&exception); } return 0; } 程序在C++ Builder 4 与Windows 98 环境下编译运行通...
-
给我们打电话
7*24小时服务热线:1399999999
全国客服热线:400-0000-000 -
百度地图
福建省漳州市 -
给我们发邮件
E-mail:[email protected]
在线沟通