2007-08-23 15:04:58| 分类: c++builder 6 | 标签: |举报 |字号大中小 订阅
---- 在实际编程应用中,当程序需要用较长的时间来处理某些计算时,这段时间有可能使WINDOWS启动屏幕保护,这样程序的处理会相对变得更长。那么如何在运行程序时自动关闭屏幕保护呢?
---- WINDOWS在启动屏幕保护前会向已激活的程序发送一个WM_SYSCOMMAND消息,并将该消息的WPARAM参数设置为SC_SCREENSAVE。我们可利用C++ BUILDER中的TApplication类的OnMessage事件来处理WINDOWS发来的这条消息,如果在接收到的消息后将handled参数设为true,这个响应的消息值就可以阻止屏幕保护运行。
---- 在C++ BUILDER 4.0的过程如下:
---- 1、从主菜单中选择File | New APPlication 来创建一个新的空工程文件。然后在Forn 上加上一个Label对象,设置其Caption为"此程序将关闭WINDOWS屏幕保护"。
---- 2、在程序头文件unit1.h中对成员函数ProcessMessage的声明加到TForm1的定义中。
class TForm1 : public TForm
{
__published: // IDE-managed Components
TLabel *Label1;
private: // User declarations
void __fastcall ProcessMessage
(TMsg &message,bool &handled);
public: // User declarations
__fastcall TForm1(TComponent* Owner);
};
---- 3、在unit1.cpp中,在程序中增加ProcessMessage函数语句:
void __fastcall TForm1::ProcessMessage
(TMsg &message,bool &handled)
{
if(message.message==WM_SYSCOMMAND
&&message.wParam==SC_SCREENSAVE)
{
handled=true;
}
}
---- 4、在TForm1的构造函数增加以下代码:
__fastcall TForm1::TForm1(TComponent* Owner): TForm(Owner)
{
Application->OnMessage=ProcessMessage;
}
显示/隐藏任务栏图标
---- 标准的Windows应用程序运行时一般都会在任务栏上显示任务图标,用户可直接用鼠标点击任务栏图标进行任务切换,但有些应用程序不使用任务栏图标,如典型的Office工具条,也有些程序可由用户定制显示方式显示或隐藏任务栏图标,如Winamp。我们的程序中也可以做到,只要调用Windows API函数SetWindowLong即可,如下:
// 隐藏任务栏图标:
SetWindowLong(Application->Handle,
GWL_EXSTYLE, WS_EX_TOOLWINDOW);
// 显示任务栏图标:
SetWindowLong(Application->Handle,
GWL_EXSTYLE, WS_EX_APPWINDOW);
信箱监视程序
----本 文 将 向 大 家 介 绍 怎 样 编 写 自 己 的 信 箱 监 视 程 序, 程 序 将 直 接 调 用WinSock 函 数 来 进 行 网 络 通 信。 除 了 具 备WinSock 编 程 知 识 之 外, 还 必 须 了 解POP3 协 议。 下 面 是 对POP3 的 一 个 粗 略 的 介 绍, 读 者 可 以 参 看RFC 1225 更 为 详 细 地 了 解 该 协 议。
一、 关 于POP3 协 议
----POP3 服 务 器 程 序 通 常 在TCP 端 口110 提 供 服 务。 当 客 户 想 要 使 用 服 务 时, 它 便 与 服 务 器 建 立 一 个TCP 连 接。 一 旦 连 接 建 立,POP3 服 务 器 就 向 客 户 发 送 一 条 欢 迎 消 息。 然 后 客 户 开 始 给 服 务 器 发 送 命 令, 服 务 器 则 给 出 相 应 的 回 答。POP3 的 命 令 由 一 个 关 键 词 或 者 关 键 词 加 参 数 组 成。 每 个 命 令 以 回 车 换 行(0xD0xA) 作 为 结 束 标 志。 对 于 所 有 的 命 令,POP3 服 务 器 都 会 提 供 一 个 回 答。 服 务 器 的 回 答 由 一 个 状 态 标 志 加 一 些 附 加 信 息 组 成。 目 前 使 用 的 两 个 标 志 是“ +OK” 和“ -ERR”, 分 别 表 示 客 户 的 命 令 是 否 合 法。 所 有 的 回 答 也 是 以 回 车 换 行 结 束。
----与 本 文 讨 论 的 话 题 相 关 的 四 个POP3 命 令 是USER、PASS、LIST 和QUIT。
USER 命 令
格 式USER name
----其 中name 是 用 户 在 该POP3 服 务 器 上 的 用 户 标 识。 客 户 应 该 在 接 到 服 务 器 的 欢 迎 消 息 后 或 者 在 上 一 个 USER 或 者PASS 失 败 之 后 可 以 发 送 此 命 令。
PASS 命 令
格 式PASS string
----其 中string 为 该 用 户 的 密 码。 客 户 在 发 送 了USER 命 令 并 且 收 到 了 +OK 的 回 答 之 后 方 可 发 送 此 命 令。 如 果 用 户 名 和 密 码 都 正 确, 服 务 器 回 答 +OK, 否 则 -ERR。
LIST 命 令
格 式LIST
----如 果 该 用 户 有 邮 件, 则LIST 命 令 会 回 答 +OK, 并 列 出 所 有 邮 件 的 标 识 符 和 大 小( 每 个 邮 件 一 行), 最 后 一 个 仅 包 含 一 个 句 点 的 行(0xD0xA0x2E) 表 示 整 个 回 答 的 结 束。 如 果 该 用 户 没 有 邮 件, 有 些 服 务 器 会 返 回 -ERR, 有 些 在 可 能 返 回 一 个 +OK 和 一 个 仅 包 含 一 个 句 点 的 行。 当 然, 客 户 必 须 在PASS 命 令 通 过 之 后 客 户 程 序 才 能 给 服 务 器 发 送LIST 命 令。
QUIT 命 令
----从POP3 服 务 器 上 退 出 登 录。
二、 实 现 相 关 函 数
----接 下 来 我 们 按 照POP3 协 议 所 定 义 的 通 信 规 则 来 实 现 一 个 名 叫POP3CheckMail 的 函 数, 只 要 调 用 此 函 数, 我 们 就 可 以 检 测 信 箱 了。
----下 面 的 代 码 是 用 与Delphi 4 兼 容 的Pascal 语 言 实 现 的, 我 们 必 须 包 含WinSock 单 元, 并 且 在 调 用 下 列 函 数 之 前 初 始 化 好WinSock 动 态 连 接 库。 初 始 化WinSock 动 态 连 接 库 的 代 码 如 下:
----if WSAStartup( $002, wsadata)<>0 then Halt;
----POP3CheckMail 的 原 型 如 下:
----function POP3CheckMail(Email,Password:String;var MailList:TStringList;var ErrorMsg:String):Bool;
----参 数 说 明:
----Email 和Password 分 别 为 用 户 的email 信 箱 名 和 口 令。
----变 量 参 数MailList 用 于 返 回 邮 件 的 标 识 和 大 小,MailList.Count 表 示 邮 件 的 封 数。
----变 量 参 数ErrorMsg 返 回 出 错 消 息。
----以 下 是POP3CheckMail 及 其 它 所 用 到 的 函 数 的 实 现 代 码。
Connect_Server 函 数
----功 能: 与 指 定 的 主 机 建 立 一 个TCP 连 接, 返 回 一 个Socket 描 述 符。 参 数host 指 定 主 机 的 名 字,Port 指 定 端 口 号。
function Connect_Server(host:string;Port:integer):integer;
var i:integer;
p:^LongInt;
phe:pHostEnt;
sin:sockaddr_in;
begin
sin.sin_family:=AF_INET;
sin.sin_port:=htons(Port);
//Get the IP for host, allowing for dotted decimal
phe:=gethostbyname(pchar(host));
if phe<>nil
then begin
p:=Pointer(phe^.h_addr_list^);
sin.sin_addr.s_addr:=p^;
end
else begin
i:=inet_addr(PChar(Host));
if i<> -1 then sin.sin_addr.S_addr:=i
end;
//create a socket
Result:=socket(PF_INET,SOCK_STREAM,0);
if (Result=INVALID_SOCKET) then Exit;
//connect to server
if Connect(Result,sin,sizeof(sin))=SOCKET_ERROR
then begin {Error handling} end;
end;
Write_Socket 函 数
----功 能: 向Socket 写 入 一 个 字 符 串。
function Write_Socket(sockfd:Integer; const s:string):Integer;
begin
result:=Winsock.Send(sockfd,pointer(s)^,Length(s),0)
end;
Socket_Readline 函 数
----功 能: 从Socket 上 读 取 一 行。
function Socket_Readline(sockfd:Integer):String;
//Read until #10
var S:String; buf:array[0..1]of Char;
n:Cardinal;
begin
buf[0]:= #0;buf[1]:= #0; S:=‘';
n:=recv(sockfd,Buf,1,0);
while n>0 do begin
buf[1]:= #0;
S:=S +buf;
if (buf[0]= #10) then Break;
n:=recv(sockfd, buf, 1, 0);
end;
Result:=Trim(S);
end;
Pop3Response 函 数
----功 能: 读 取POP3 服 务 器 的 一 行 返 回 信 息, 如 果 是“ +OK” 则 函 数 返 回TURE, 如 果 是“ -ERR” 则 返 回FALSE。
function Pop3Response(Sockfd:Integer):Bool;
var S: string;
begin
S:=socket_readline(sockfd);
if copy(s,1,3)=‘ +OK' then Result:=True
else {if copy(s,1,4)=‘ -ERR' then }Result:=False;
end;
POP3CheckMail 函 数
----功 能: 检 测 名 字 为email 的 信 箱, 如 果 有 新 邮 件, 则 通 过 变 量 参 数MailList 将 每 一 封 邮 件 的 大 小 返 回。
function POP3CheckMail
(Email,Password:String;var MailList:
TStringList;var ErrorMsg:String):Bool;
var sockfd,i:integer;
S, Host, User:String;
begin
Result:=False; ErrorMsg:=‘';
if MailList=nil then Exit;
S:=Trim(Email);
i:=Pos(‘@',Email);
User:=Trim(Copy(S,1,i -1));
Host:=Trim(Copy(S,i +1,Length(Email) -i));
MailList.Clear;
if (user=‘')or(host=‘') then begin
ErrorMsg:=‘Invalid email address.';exit; end;
if (Host[1]=‘[')and (Host[Length(host)]=‘]')
then begin Host[1]:=‘ ';Host[Length(host)]:= #0;end;
Host:=Trim(host);
sockfd:=Connect_Server(Host,110);
if not Pop3Response(sockfd)then begin ErrorMsg:=
‘Cannot connect to server';exit; end;
Write_Socket(sockfd,‘USER ' +User + #13 #10);
IF NOT POP3Response(sockfd) then begin ErrorMsg:=
‘USER failed'; Exit;end;
Write_Socket(sockfd,‘PASS ' +Password + #13 #10);
IF NOT POP3Response(sockfd) then begin ErrorMsg:=
‘PASS failed'; Exit;end;
Write_Socket(sockfd,‘LIST' #13 #10);
POP3Response(sockfd);
while true do begin
s:=Socket_readline(sockfd);
if s=‘.' then BREAK;
MailList.Add(S);
end;
Write_Socket(sockfd,‘QUIT' #13 #10);
Closesocket(sockfd);
Result:=True;
end;
三、 邮 件 的 检 测
----下 面 我 们 来 看 一 个 使 用POP3CheckMail 函 数 的 简 单 示 例。
var MailList:TstringList;
ErrorMsg:String;
...
MailList:=TstringList.Create;
POP3CheckMail(‘simon_liu@263.net',
‘mypassword', MailList, ErrorMsg);
If MailList.Count>0 then
MessageBox(0, Pchar(‘You have ' +IntToStr (MailList.Count) + ‘ new messages!'),
‘New Message!', MB_ICONINFORMATION)
Else if ErrorMsg=‘' then MessageBox (0, ‘No message!', ‘',0)
Else MessageBox(0, Pchar(ErrorMsg), ‘Error', 0);
MailList.Free;
----如 果 你 仔 细 阅 读 了POP3CheckMail 函 数 的 实 现 代 码, 你 会 发 现 此 函 数 除 了 可 以 获 取 邮 件 的 封 数 之 外, 还 可 以 获 得 每 一 封 邮 件 的 大 小。 你 可 以 通 过POP3CheckMail 函 数 的 变 量 参 数MailList 的Strings 数 组 来 获 取 邮 件 的 大 小。
----实 现 了POP3CheckMail 函 数, 再 在 此 基 础 上 编 写 一 个POP3 信 箱 的 监 视 程 序 就 变 得 很 简 单 了。 你 可 以 通 过 一 个 定 时 器 来 定 期 地 调 用POP3CheckMail 函 数, 这 样 你 就 可 以 监 视 某 个email 信 箱 了。 假 若 你 想 要 同 时 监 视 多 个email 信 箱, 只 要 为 每 一 个 信 箱 创 建 一 个 线 程 并 且 在 线 程 中 定 期 调 用POP3CheckMail 函 数 即 可。 你 的 程 序 中 如 果 没 有 使 用Delphi 的 控 件, 那 么 一 个 完 整 的 信 箱 监 视 程 序 可 能 只 有60K 左 右。
C++Building制作闹钟
---- 大凡热恋中的网虫都曾经陷入下列的困境:约好女/男朋友晚七点半在老地方等,却在计算机面前一直爬行到深夜,等反映过来,朋友早已拂尘而去,又得几天的功夫去陪礼道歉。朋友何不按以下步骤做一简单的闹钟,让你安安心心上网,大大方方约会。你只要在上网的时候打开此应用程序,设置好约会时间(当然也可以是默认好的)即可。时间一到,音乐响起,快去约会吧。
---- 本闹钟程序有以下组件组成:
序号 组件类型 组件名称 功能
1 Tlabel l_Clock_1 显示“输入日期”
2 TdateTimePicker dtp_Clock_1 选择日期
3 Tlabel l_Clock_2 显示“输入时间”
4 TdateTimePacker tdp_Clock_2 选择时间
5 TmediaPlayer mp_Clock 演奏音乐
6 Tbutton b_Clock_Open 重新打开
7 Ttimer t_Clock 定时检测
8 Tbutton b_Clock_Close 关闭应用程序
---- 屏幕组件一览表
---- 屏幕组件一览图
---- 说明:dtp_Clock_1 的Kind属性设置为dtkDate , dtp_Clock_2 的Kind属性设置为dtkTime,mp_Clock 的FileName属性设置为你主机上存在的任何mid、wav、avi文件。t_Clock 的Interval属性设置为10。
---- 事件说明如下:
①、 t_Clock的OnTimer :
{
//按时触发演示程序
struct date d;
struct time t;
AnsiString thour,tmin,tsec;
int dyear;
int dintyear;
int dmon,dday;
AnsiString tinthour,tintmin,tintsec;
AnsiString dintmon,dintday;
//取当天日期
getdate(&d);
dyear=d.da_year;
dday=d.da_day;
dmon=d.da_mon;
dintyear=StrToInt(dint.SubString(1,2));
dintmon=dint.SubString(4,2);
dintday=dint.SubString(7,2);
//取当时时间
gettime(&t);
thour=AnsiString(t.ti_hour);
tmin=AnsiString(t.ti_min);
//tsec=AnsiString(t.ti_sec);
//tint=AnsiString(DateTimePicker1- >Time);
tinthour=tint.SubString(10,2);
tintmin=tint.SubString(13,2);
//tintsec=tint.SubString(16,2);
//闹钟服务功能
if ((StrToInt(thour)==StrToInt(tinthour))&&
(StrToInt(tmin)==StrToInt(tintmin))
&&(StrToInt(AnsiString(dyear).SubString(3,2))
==dintyear)&&(StrToInt(dmon)==StrToInt(dintmon))
&&(StrToInt(dday)==StrToInt(dintday)))
{
dTimer- >Enabled=false;
MediaPlayer1- >Open();
MediaPlayer1- >Play();
}
}
②、 b_Clock_Open 的OnClick:
{
t_Clock- >Enabled=true;
}
③、 b_Clock_Close的OnClick
{
Application- >Terminate();
}
---- 当然此程序还可以拓展、细化,如我仅将触发条件检测到分,当然它完全可以检测到秒,也可以仅检测到时。
拨号上网IP地址的检知
随着INTERNET在世界范围内的迅速普及,上网的人数也越来越多。其中,绝大多数人是通过普通电话线拨号上网的。我们知道,每一台上网的计算机,不论是用何种方式上网,都被分配了一个或多个独立无二的IP地址。对于拨号上网的用户,一般是由其ISP在其每次拨号上网时动态分配一个IP地址,这个地址可能每次都不相同(其原因主要是为了充分利用有限资源)。那么,我们能否通过某种方法随时方便地检知自己上网时的IP地址呢?答案是肯定的。下面我们就用C++BUILDER编制一个小巧的程序来实现这种功能。(注:本程序在局域网中也同样能运行)
---- 首先用BCB的FILE菜单下的New Application创建一个新项目,取名为Ipcheck.bpr。
---- 然后,在窗体FORM1上添加五个标签(LABEL)和两个按钮(BUTTON),如图所示。
---- 接下来,双击窗体的OnCreate事件,在其中加上以下程序:
void __fastcall TForm1::FormCreate(Tobject *Sender)
{
WSAData wsaData;
if (WSAStartup(MAKEWORD(1,1),&wsaData)!=0)
{ //初始化WINSOCK调用
MessageBox(NULL,"Wrong WinSock
Version","Error",MB_OK);
return ;
}
Refresh1Click(Sender); //程序一开始,就调检知IP地址
}
再双击Refresh按钮,在其中加上以下程序
void __fastcall TForm1::Refresh1Click(Tobject *Sender)
//刷新IP地址
{
char HostName[80];
LPHOSTENT lpHostEnt;
struct in_addr addr[2];
//本程序假设主机不是多宿主机,即最多只有
// 一块网卡和一个动态IP
for (int I=0; I< 2; I++){
memset(&addr[I],0,sizeof(in_addr));
//对in_addr结构清0,以利后面填写
}
if (gethostname(HostName,sizeof(HostName))==SOCKET_ERROR)
{ // 得到本主机名
MessageBox(NULL,"Can't getting local host name.","Error",MB_OK);
return ;
}
Label3- >Caption=HostName;
lpHostEnt=gethostbyname(HostName);//利用得到的主机名去获得主机结构
if (!lpHostEnt){
MessageBox(NULL,"Yow! Bad host lookup.","Error",MB_OK);
return ;
}
for (int I=0; lpHostEnt- >h_addr_list[I]!=0; I++)
//从主机地址表中得到IP地址
{
memcpy(&addr[I],lpHostEnt- >h_addr_list[I],sizeof(in_addr));
}
Label4- >Caption=inet_ntoa(addr[0]);
Label5- >Caption=inet_ntoa(addr[1]);
}
再双击Refresh按钮,在其中加上以下程序
void __fastcall TForm1::Button2Click(Tobject *Sender)
{
WSACleanup(); //释放WINSOCK调用
Close();
}
---- 最后,不要忘了在程序头部加上#include<winsock.h>.....哦。
---- 好了,程序完成了,编译后就可运行了。本程序在中文WIN95/NT4.0下编译通过。
用C++ Builder编写Tray程序
Tray(托盘)是Windows9x任务条上的一个特殊区域,它的技术名称为“任务栏布告区”,一些软件(如金山词霸Ⅲ)运行时会在托盘上放置一个图标,使用户一眼就能知道这个程序正在后台运行,要想激活它也很容易,通常只需单击一下这个图标即可,非常方便。
Tray的编程比较特殊,但并不难,主要包括图标、工具提示和消息等三个方面,它是Shell编程的一部分。ShellAPI提供了Shell-NotifyIcon函数,用它可以增加、删除或者修改托盘中的图标,在托盘上放置图标后,Windows Shell会负责把发生在图标上的鼠标事件通知应用程序。Shell-NotifyIcon函数定义如下:
WINSHELLAPI BOOL WINAPI Shell-NotifyIcon(DWORD dwMessage,PNOTIFYICONDATA pnid);
dwMessage表示要完成的操作:NIM-ADD(增加图标)、NIM-DELETE(删除图标)、NIM-MODIFY(修改图标或提示文本),pnid是一个指向NOTIFYICONDATA结构的指针,结构的定义如下:
typedef struct -NOTIFYICONDATA{
DWORD cbSize;//结构所占的字节数,必须用结构的大小来初始化。
HWND hWnd;//接受Tray图标消息的窗口句柄
UINT uID;//由应用程序定义的图标ID
UINT uFlags;//用来鉴别那些需要改变其值的域,NIF_ICON表示hIcon有效,可用来修改图标,NIF_MESSAGE表示uCallbackMessage有效,用来定义消息,NIF-TIP表示szTip参数有效,可修改工具提示。
UINT uCallbackMessage;//应用程序定义的消息
HICON hIcon;//Tray图标的句柄
char szTip[64];//工具提示的文本
}NOTIFYICONDATA;
下面我们就通过一个具体例子来说明实现方法,程序运行时不会显示主窗体,只在托盘上增加一个图标,双击图标可关闭程序。
程序运行时托盘区显示如下:
新建一个工程,放置一个Timer控件到窗体上。打开unit1.h文件,增加头文件说明#include <shellapi.h>,在TForm1定义的private段增加一些数据成员和方法的声明:
unsigned int iconmessage;//定义的消息
void AddTrayIcon();//在托盘上增加图标
void RemoveTrayIcon();//从托盘中删除图标
由于要增加对自定义消息的处理,所以必须重载窗口过程函数WndProc,在TForm1的定义中增加protected段:virtual void --fastcall WndProc(Messages::Tmessage& Message);
在unit1.cpp中定义相应的成员函数:
void TForm1::AddTrayIcon()
{
NOTIFYICONDATA icondata;
memset(&icondata,0,sizeof(icondata));
//将结构icondata的各域初始化为0
icondata.cbSize=sizeof(icondata);
icondata.hWnd=Handle;
strncpy(icondata.szTip,″未知状态″,sizeof(icondata.szTip));
icondata.hIcon=Application->Icon->Handle;
icondata.uCallbackMessage=iconmessage;
icondata.uFlags=NIF-MESSAGE|NIF-ICON|NIF-TIP;
Shell-NotifyIcon(NIM-ADD,&icondata);
}
void TForm1::RemoveTrayIcon()
{
NOTIFYICONDATA icondata;
memset(&icondata,0,sizeof(icondata));
icondata.cbSize=sizeof(icondata);
icondata.hWnd=Handle;
Shell-NotifyIcon(NIM-DELETE,&icondata);
}
重载TForm1的WndProc函数,加入对自定义消息的处理代码,这其实相当于创建了TForm类的子类。
void __fastcall TForm1::WndProc(Messages::TMessage& Message)
{
if(Message.Msg==iconmessage)
{
if(Message.LParam==WM-LBUTTONDBLCLK)
{
Application->Terminate();
//如果双击图标,则关闭应用程序
}
return;
}
TForm::WndProc(Message);//对于其他的消息,调用基础类的WndProc函数让Windows进行缺省处理。
}
创建窗体的OnCreate事件句柄:
void --fastcall TForm1::FormCreate(TObject *Sender)
{
iconmessage=RegisterWindowMessage(″IconNotify″);
AddTrayIcon();
}
这里通过调用RegisterWindowMessage函数来定义一个用户消息,也可以通过WM_USER+n来获得一个系统没有使用的消息编号。
void --fastcall TForm1::FormDestroy(TObject *Sender)
{
RemoveTrayIcon();
//窗体在关闭时删除托盘中的图标
}
编写Timer1的Timer事件代码,当用户将鼠标停留在图标上时,显示提示文本:
void --fastcall TForm1::Timer1Timer(TObject *Sender)
{
NOTIFYICONDATA icondata;
memset (&icondata, 0, sizeof (icondata));
icondata.cbSize = sizeof (icondata);
icondata.hWnd = Handle;
String s=″我的图标!″;//定义提示文本
strncpy (icondata.szTip, s.c_str(), sizeof (icondata.szTip));
icondata.uFlags = NIF-TIP ;
Shell-NotifyIcon (NIM-MODIFY,&icondata);
}
程序运行时不显示主窗体,只在托盘上放置相应的程序图标,从C++ Builder主选单中选择View|Project Source,在WinMain函数的Application→Initialize()语句后增加代码:
ShowWindow(Application→Handle,SW-HIDE);
Application→ShowMainForm=false;
按F9编译并运行程序,托盘上就会出现相应的图标。以上代码在C++ Builder3、Pwin98环境下编译、运行通过。
怎样用代码来最小化或恢复程序
你能够用下面三种方法之一来实现它。
方法一:发送一条Windows消息到主窗口的Handle属性或 Application->Handle。这条消息就是 WM_SYSCOMMAND,将 wParam 设为 SC_MINIMIZE 或 SC_RESTORE。你可以调用SendMessage API函数来发送消息。 // 设置WPARAM为SC_MINIMIZE来最小化窗口
SendMessage(Application->Handle, WM_SYSCOMMAND, SC_MINIMIZE, 0);
// 设置WPARAM为SC_RESTROE来恢复窗口
SendMessage(Application->Handle, WM_SYSCOMMAND, SC_RESTORE, 0);
方法二:调用 ShowWindow API 函数。
你必须传送Application对象句柄到ShowWindow函数。如果你传送给ShowWindow函数的句柄是主窗口,那么主窗口将最小化到桌面(desktop)而不是任务条(taskbar)。 // 最小化:传送 SW_MINIMIZE 到 ShowWindow
ShowWindow(Application->Handle, SW_MINIMIZE);
// 恢复:传送SW_RESTORE 到 ShowWindow
ShowWindow(Application->Handle, SW_RESTORE);
方法三:调用Application对象的Minimize或Restore函数。 // 调用Minimize最小化应用程序
Application->Minimize();
// 调用Restore恢复应用程序
Application->Restore();
调用Application的方法较易用,但发送WM_SYSCOMMAND消息功能更强。
另外,WM_SYSCOMMAND消息允许你最大化程序,改变光标为帮助光标,滚动程序,移动一个窗口,改变窗口大小,甚至模拟Alt-TAB切换到另一窗口。紧记,实现这些功能用API函数更好。
尽管调用ShowWindow也能工作,你大概也不想用它来最小化或恢复程序。当隐藏的窗口被最小化时ShowWindow会引起最小化动画出现。这看上去稍微有点傻,因为动画是从程序主窗口的位置远离中心。
制作主窗口显示前的版权窗口
在工程文件中选File->New Form新建一个窗口,设计好窗口的外观。
给窗口起名为AboutBox,源文件命名为AboutBox.Cpp
选Project->Options,将新建的窗口从自动建立中去掉。
选View->Project Source,打开工程文件的源文件,加入句子。
#include "AboutBox.h"
WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
DWORD lTime;
try
{
Application->Initialize();
AboutBox=new TAboutBox(AboutBox);
AboutBox->Show();
AboutBox->Update();
lTime=GetTickCount();
Application->CreateForm(__classid(TMainForm), &MainForm);
while((GetTickCount()-lTime) / 1000 <3);
AboutBox->Hide();
AboutBox->Free();
Application->Run();
}
catch (Exception &exception)
{
Application->ShowException(&exception);
}
return 0;
}
评论