国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發(fā)設計 > 正文

BCB控件制作和消息處理

2019-11-17 05:45:01
字體:
供稿:網(wǎng)友

  1 前言

作為和Delphi類似的rad(rapid application development)工具,c++ builder的強大功能不僅體現(xiàn)在數(shù)據(jù)庫開發(fā)方面,也凸現(xiàn)于應用程序開發(fā)上(令人稱絕的是這兩方面結(jié)合得非常好)。僅就應用程序而言,要真正體現(xiàn)c++ builder的優(yōu)勢,開發(fā)出高質(zhì)量的軟件,則在拖拉拽放之外,尚需用到一些進階技術(shù)。如消息處理、dll、ole、線程、sdk編程。c++ builder在這些方面都或多或少有獨到的優(yōu)勢。此外,可以方便地制作自定義控件,也是c++ builder的一大特色和高級功能。本文將通過制作一個標題棒在窗口左邊的對話框控件,來示范一些c++ builder中關(guān)于控件制作和消息處理的概念,同時涉及到一點sdk編程。我們將要制作的是一個對話框,就如同opendialog等一樣,一調(diào)用其execute()方法,就彈出一個如圖一所示的窗口。這個窗口的標題棒位于左方,綠色,文字走向為由下而上的90度字形,其功能和一般的標題棒相同,可以將鼠標移至該處來移動該窗口。
首先來完成這個窗口,然后用它來制作對話框控件。

圖一
2 利用wm_nchittest消息制作豎直標題的窗口
.wm_nchittest消息
c++builder將某些windows消息封裝于事件(event)中,但無法囊括所有消息,如wm_nc**** 系列消息。wm_nchittest消息發(fā)生于游標(cursor)移動或鼠標按下、釋放時,返回值指示目前游標所在位置,如返回hthscroll表示處于水平滾動條內(nèi),返回htcaption表示處于標題棒內(nèi)(參見win32 sdk help)。其參數(shù)XPos、ypos分別表示游標的x、y坐標(相對于屏幕左上角),分別對應于lparam的低字和高字。假如攔截wm_nchittest消息,使得當鼠標在窗口左邊按下時,人為地將返回值設為htcaption,則系統(tǒng)將以為是在標題棒內(nèi),于是將可以移動窗口,完成了標題棒的功能,至于顏色和文字,則與消息無關(guān),將在下面敘述其原理。
.windows消息
消息就是windows操作系統(tǒng)送往程序的事件。但事件數(shù)以百計,操作系統(tǒng)并沒有為各個事件設計不同的消息結(jié)構(gòu),而是以一個一般性的結(jié)構(gòu)來來描述消息,這個結(jié)構(gòu)在c++ builder中定義為tmessage。另外c++ builder對常見消息定義了專用結(jié)構(gòu),二者對等。可以直接將消息轉(zhuǎn)換為專用結(jié)構(gòu),也可以自行解釋tmessage參數(shù)。以wm_nchittest消息為例,它的定義如下:
strUCt twmnchittest
{
cardinal msg;
long unused;
union
{
struct
{
windows::tsmallpoint pos;
long result;
};
struct
{
short xpos;
short ypos;
};
};
};
對照tmessage定義:
struct tmessage
{
cardinal msg;
union
{
struct
{
Word wparamlo;
word wparamhi;
word lparamlo;
word lparamhi;
word resultlo;
word resulthi;
};
struct
{
long wparam;
long lparam;
long result;
};
};
};
可以發(fā)現(xiàn),tmessage的lparam成員對應twmnchittest的pos成員,就是說以下兩行語句
等價:
tpoint pt=tpoint(msg.lparam); //此時msg類型為tmessage
tpoint pt=tpoint(msg.pos); //此時msg類型為twmnchittest
.c++ builder處理消息的宏
在c++ builder中自定義消息處理是較為方便的,結(jié)合wm_nchittest舉例如下:

在窗口類的PRotected部分加入如下宏定義:
begin_message_map
message_handler(wm_nchittest,tmessage,onnchittest)
end_message_map(tform)
message_handler包含3個參數(shù):wm_nchittest,消息標識,也可以為自定義消息如wm_mymessage,這時只需加一個宏如#define wm_mymessage wm_app+1等;第二個參數(shù)tmessage代表消息類型,也可以為符合要求的自定義消息結(jié)構(gòu)類型如tmymsg等,onnchittest為消息處理函數(shù)。這樣,一旦有wm_nchittest消息傳給tform,對該消息的響應就完全交由onnchittest函數(shù)處理。onnchittest函數(shù)只有一個參數(shù),類型為message_handler中第2個參數(shù)的引用,即tmessage &或tmymsg &。
.完成圖一的窗口。
開始一個新應用程序(new application),將form1命名為vcform,對應單元文件為vcap.cpp,頭文件為vcap.h。vcform的boarderstyle設置為bsnone,其上放置一個位圖按鈕bitBTn1,caption為&ok,kind為bkok,onclick事件處理函數(shù)中加入一句close()。然后在vcap.h的protected部分加入如前所述消息處理宏和函數(shù)onnchittest的聲明,以處理標題條的拖動功能。為完成標題的著色和文字輸出,雙擊vcform的onpaint事件以定制formpaint函數(shù),具體代碼見下面源碼。此外為使窗口有立體感,重載虛函數(shù)createparams,以修改窗口的風格。完整的vcap.h和vcap.cpp如下:
//vcap.h
#ifndef vcaph
#define vcaph
#include
#include
#include
#include
#include
class tvcform : public tform
{
__published: // ide-managed components
tbitbtn *bitbtn1;
void __fastcall formpaint(tobject *sender);
void __fastcall bitbtn1click(tobject *sender);
private: // user declarations
protected:
void __fastcall onnchittest(tmessage & msg);
void __fastcall createparams(tcreateparams& params);
begin_message_map
message_handler(wm_nchittest,tmessage,onnchittest)
end_message_map(tform)
public: // user declarations
__fastcall tvcform(tcomponent* owner);
};
extern package tvcform *vcform;
#endif
//vcap.cpp
#include
#pragma hdrstop
#include "vcap.h"
#pragma package(smart_init)
#pragma resource "*.dfm"
tvcform *vcform;
__fastcall tvcform::tvcform(tcomponent* owner)
: tform(owner)
{
}
void __fastcall tvcform::formpaint(tobject *sender)
{
//繪制寬20的綠色標題條
rect rc;
setrect(&rc,0,0,clientwidth,clientheight);
canvas->pen->color=clgreen;
canvas->brush->color=clgreen;
canvas->rectangle(0,0,20,clientheight);
//輸出旋轉(zhuǎn)文字
char* msg=caption.c_str();
logfont fontrec;
memset(&fontrec,0,sizeof(logfont));
fontrec.lfheight = -13;
fontrec.lfweight = fw_normal;
fontrec.lfescapement = 900; //旋轉(zhuǎn)角度900x0.1度=90度
lstrcpy(fontrec.lffacename,"宋體");
hfont hfont=createfontindirect(&fontrec);
hfont hold=::selectobject(canvas->handle,hfont);
::setrect(&rc,0,0,20,clientheight);
::settextcolor(canvas->handle,rgb(255,255,255));
::textout(canvas->handle,3,clientheight-3,msg,lstrlen(msg));

::selectobject(canvas->handle,hold);
::deleteobject(hfont);
}
void __fastcall tvcform::bitbtn1click(tobject *sender)
{
close();
}
void __fastcall tvcform::onnchittest(tmessage & msg)
{
tpoint pt;
pt.x=loword(msg.lparam);
pt.y=hiword(msg.lparam);
pt =screentoclient(pt);
rect rc;
setrect(&rc,0,0,20,clientheight);
if (ptinrect(&rc,pt))
msg.result = htcaption;
else
defaulthandler(&msg);
}
void __fastcall tvcform::createparams(controls::tcreateparams& params)
{
tform::createparams(params);
params.style = ws_popup;
params.style ^= ws_dlgframe;
}
vcform的消息處理已經(jīng)介紹過,這里再對標題條的繪制作簡要說明。由于c++builder的tfont沒有定義文字旋轉(zhuǎn)旋轉(zhuǎn)的屬性,因此用傳統(tǒng)的sdk繪圖方法。canvas->handle即是代表gdi繪圖的hdc。
3 制作對話框控件在開始制作控件之前,先將vcap.cpp中的#pragma package(smart_init)行注釋掉。創(chuàng)建控件的步驟是:創(chuàng)建一個單元文件,在其中完成控件的類定義和注冊,然后就可以安裝了。控件類一般從某個現(xiàn)有類繼續(xù)導出。制作控件與一般類定義的主要區(qū)別在于屬性(property)和事件(event),事件也是屬性。由屬性就帶來了屬性的存取方法、缺省值、屬性編輯器等問題。為簡單起見,本控件只涉及到上述一部分概念,但能涵蓋控件制作的一般過程。
.開始一個空控件
由于要制作的對話框控件的最小必要功能是一個execute()方法,因此可以從tcomponent類繼續(xù)。命名控件名為tvcaptiondlg,定義控件的單元文件命名為vcapdlg.cpp,其頭文件為vcapdlg.h。用component wizard或手工方法完成如下文件:
//vcapdlg.h
#ifndef vcapdlgh
#define vcapdlgh
#include
#include
#include
#include
class package tvcaptiondlg: public tcomponent
{
private:
protected:
public:
virtual __fastcall tvcaptiondlg(tcomponent

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 孟津县| 福州市| 昭苏县| 左云县| 中方县| 东辽县| 宜兴市| 阜城县| 盘锦市| 米林县| 翁源县| 南安市| 彭州市| 贡觉县| 蒲江县| 荣成市| 隆回县| 上蔡县| 沂水县| 深水埗区| 奈曼旗| 玉门市| 湘西| 凤阳县| 吴忠市| 安远县| 玛曲县| 绍兴市| 自治县| 娄烦县| 清流县| 偃师市| 黑水县| 涞源县| 宁德市| 西宁市| 汤原县| 中江县| 荥经县| 辛集市| 涪陵区|