MiniGUI细节处理(转)
MiniGUI編程--列表框
分類: minigui2009-11-04 20:40
列表框
LBS(ListBoxStyle)
以CTRL_LIST/"list"為類名調(diào)用CreateWindow
多選風(fēng)格:LBS_MULTIPLESEL
高級(jí)風(fēng)各:LBS_USEICON
LBS_CHECKBOX
LBS_AUTOCHECK
加上邊框WS_BORDER
加垂直滾動(dòng)條WS_VSCROLL
加水平滾動(dòng)條WS_HSCROLL
允許通知消息:LBS_NOTIFY
排序LBS_SORT
常用風(fēng)格組合:
LBS_NOTIFY|LBS_SORT|WS_VSCROLL|WS_BORDER
加入字符串LB_ADDSTRING
最上面索引值為0
SendMessage傳遞字符串時(shí)節(jié)lParam指向字符串
添加以未尾
SendMessage(hwndlist,LB_ADDSTRING,0,(LPARAM)string);
插入字符串LB_INSERTSTRING
SendMessage(hwndlist,LB_INSERTSTRING,index,(LPARAM)string);
如指定期LBS_CHECKBOX/LBS_USEICON風(fēng)格添加時(shí)不能傳字符串指針,而要使用LISTBOXITEMINFO結(jié)構(gòu)
HICON hIcon1;
LISTBOXITEMINFO lbii;
hIcon1=LoadIconFromFile(HDC_SCREEN,"res/audio.ico",1);
lbii.hIcon=hIcon1;
lbii.cmFlag=CMFLAG_CHECKED;
lbii.string="ABCDEFG";
SendMessage(hwnd,LB_ADDSTRING,0,(LPARAM)&lbii);
cmFlag:CMFLAG_CHECKED,CMFLAG_BLANK,CMFLAG_PARTCHECKED
在列表框中顯示位圖
IMGFLAG_BITMAP
lbii.hIcon=(DWORD)GetSystemBitmap(SYSBMP_MAXIMIZE);
lbii.cmFlag=CMFLAG_CHECKED|IMGFLAG_BITMAP;
lbii.string="ABCDEF";
SendMessage(hwndlist,LB_ADDSTRING,0,(LPARAM)&lbii);
刪除指定條目
發(fā)送LB_DELETESTRING消息
SendMessage(hwndlist,LB_DELETESTRING,index,0);
清空
SendMessage(hwndlist,LB_DELETESTRING,0,0);
獲取條目個(gè)數(shù)
發(fā)送LB_GETCOUNT消息
count=SendMessage(hwndlist,LB_GETCOUNT,0,0);
獲取指定條目字符串長(zhǎng)度
發(fā)送LB_GETTEXTLEN
length=SendMessage(hwndlist,LB_GETTEXTLEN,index,0);
獲取條目
length=SendMessage(hwndlist,LB_GETTEXTLEN,index,(LPARAM)buffer);
設(shè)置條目
LB_SETTEXT
SendMessage(hwndlist,LB_SETTEXT,index,buffer);
高級(jí)列形框要使用LB_GETITEMDATA/LB_SETITEMDATA
HICON hIocn1;
LISTBOXITEMINFO lbii;
hIcon1=LoadIconFromFile(HDC_SCREEN,"rest/audio.ico",1);
lbii.hIcon=hIcon1;
lbii.cmFlag=CMFLAG_CHECKED;
lbii.string="new item";
SendMessage(hwndlist,LB_SETITEMDATA,index,(LPARAM)&lbii);
獲取當(dāng)前選擇項(xiàng)
LB_GETCURSEL
index=SendMessage(hwndlist,LB_GETCURSEL,0,0);
設(shè)置當(dāng)前選擇項(xiàng)
SendMessage(hwndlist,LB_SETCURSEL,index,0);
多選:
LB_GETSELCOUNT獲得被選中的條目個(gè)數(shù)
LB_GETSELITEMS獲得所有被選索引值
int i,sel_count;
int *sel_itmes;
sel_count=SendMessage(hwndlist,LB_GETSELCOUNT,0,0L);
if(sel_count==0)
return;
sel_items=alloca(sizeof(int)*sel_count);
SendMessage(hwndlist,LB_GETSELITEMS,sel_count,sel_items);
for(i=0;i<sel_count;i++)
...
查所字符串
模糊查找LB_FINDSTRING
精確查找LB_FINDSTRINGEXACT
index=SendMessage(hwndlist,LB_FINDSTRING,(LPARAM)string);
獲取檢查框狀態(tài)
status=SendMessage(hwndlist,LB_GETCHECKMARK,index,0);
返回值:
CMFLAG_CHECKED選擇狀態(tài)
CMFLAG_PARTCHECKED部分選擇狀態(tài)
CMFLAG_BLANK未選擇狀態(tài)
設(shè)檢查框狀態(tài)
ret=SendMessage(hwndlist,LB_SETCHECKMARK,index,(LPARAM)status);
返回值:
LB_ERR失敗
LB_OKAY成功
為每個(gè)條目附加一個(gè)32位數(shù)據(jù),在需要時(shí)取出該值
LB_SETITEMADDDATA
LB_GETITEMADDDATA
設(shè)置條目所占高度
LB_SETITEMHEIGHT
返回條目所占高度
LB_GETITEMHEIGHT
通知碼:
必須指定LBS_NOTIFY風(fēng)格
LBN_ERRSPACE內(nèi)存分配失敗
LBN_SELCHANGE當(dāng)前選擇項(xiàng)發(fā)生變化
LBN_CLICKED單擊
LBN_DBLCLK雙擊
LBN_SELCANCEL取消選擇
LBN_SETFOCUS列表框獲得焦點(diǎn)
LBN_KILLFOCUS列表框失去焦點(diǎn)
LBN_CLICKCHECKMARK單擊條目檢查框
LBN_ENTER在列表框中按下Enter鍵
只有指下LBS_NOTIFY時(shí),列表框才會(huì)向父窗口發(fā)送通知消息
如果用SetNotificationCallback設(shè)定了通知回調(diào)函數(shù)
則控件不發(fā)送MSG_COMMAND通知消息,而會(huì)直接調(diào)用設(shè)定的通知回調(diào)函數(shù)
MiniGUI編程--編輯框
2009-11-04 20:41
編輯框
ES(EditStyle)
單行CTRL_SLEDIT/"sledit"? SingleLineEdit
多行CTRL_MLEDIT/"textedit"? MultiLineEdit
通用風(fēng)格
WS_CHILD|WS_VISIBLE|WS_BORDER
特有風(fēng)格:
ES_UPPERCASE大寫(xiě)
ES_LOWERCASE小寫(xiě)
ES_PASSWORD密碼
ES_READONLY只讀
ES_BASELINE顯示虛線
ES_AUTOWRAP自動(dòng)換行
ES_LEFT左對(duì)齊
ES_NOHIDESEL失去焦點(diǎn)保持文本的選中狀態(tài)
ES_AUTOSELECT得到焦點(diǎn)時(shí)自動(dòng)先選中所有
ES_TITLE第一行顯示標(biāo)題
ES_TIP提示信息
ES_CENTER文本居中對(duì)齊
ES_RIGHT文本右對(duì)齊
多行文本框指定滾動(dòng)條:
WS_HSCROLL
WS_VSCROLL
消息:
MSG_GETTEXTLENGTH獲取文本長(zhǎng)度
MSG_GETTEXT獲取文本
MSG_SETTEXT設(shè)置文本
或用以下函數(shù)
GetWindowTextLength
GetWindowText
SetWindowText
取得插入符位置
EM_GETCARETPOS
int line_pos;
int char_pos;
SendMessage(hwndedit,EM_GETCARETPOS,(WPARAM)&line_pos,(LPARAM)&char_pos);
參數(shù):
line_pos行索引值
char_pos該行中的字符位置
設(shè)置插入符位置
EM_SETCARETPOS
int line_pos;
int char_pos;
SendMessage(hwndedit,EM_SETCARETPOS,line_pos,char_pos);
獲取當(dāng)前選中文本
EM_GETSEL
char buffer[buf_len];
SendMessage(hwndedit,EM_GETSEL,buf_len,(LPARAM)buffer);
設(shè)置當(dāng)前選中的文本
EM_SETSEL
int line_pos,char_pos;
SendMessage(hwndedit,EM_SETSEL,line_pos,char_pos);
lParam指定行索引值,wParam指定行內(nèi)字符位置
獲取當(dāng)前選擇點(diǎn)位置
EM_GETSELPOS
int line_pos,char_pos;
SendMessage(hwndedit,EM_GETSELPOS,(WPARAM)&line_pos,(LPARAM)&char_pos);
選擇所有字符相當(dāng)于Ctrl+A
EM_SELECTALL
SendMessage(hwndedit,EM_SELECTALL,0,0);
復(fù)制到剪貼板Ctrl+C
EM_COPYTOCB CopyToClipBoard
SendMessage(hwndedit,EM_COPYTOCB,0,0);
粘貼到編輯框Ctrl+V
EM_INSERTCBTEXT InsertClipBoardText
SendMessage(hwndedit,EM_INSERTCBTEXT,0,0);
剪切Ctrl+X
EM_CUTTOCB CutToClipBoard
SendMessage(hwndedit,EM_CUTTOCB,0,0);
獲取行高
EM_GETLINEHEIGHT
int line_height;
line_height=SendMessage(hwndedit,EM_GETLINEHEIGHT,0,0);
設(shè)置行高
EM_SETLINEHEIGHT
int line_height;
SendMessage(hwndedit,EM_SETLINEHEIGHT,line_height,0);
獲取行數(shù)
EM_GETLINECOUNT
int line_count;
line_count=SendMessage(hwndedit,EM_GETLINECOUNT,0,0);
設(shè)置文本上限
EM_LIMITTEXT
SendMessage(hwndedit,EM_LIMITTEXT,10,0L);
設(shè)置只讀
EM_SETREADONLY wParam為T(mén)RUE
取消只讀
EM_SETREADONLY wParam為FALSE
修改密碼顯示字符
EM_SETPASSWORDCHAR
SendMessage(hwndedit,EM_SETPASSWORDCHAR,'%',0L);
獲得當(dāng)前密碼字符
EM_GETPASSWORDCHAR
設(shè)置提示文字
SLEDIT控件具有ES_TIP風(fēng)格時(shí)
ES_SETTIPTEXT
獲取提示文字
ES_GETTIPTEXT
int len;
char *tip_text;
SendMessage(hwndedit,ES_SETTIPTEXT,len,(LPARAM)tip_text);
lParam指定字符串,wParam指定長(zhǎng)度
或
int len;
char tip_text[len+1];
SendMessage(hwndedit,EM_GETTIPTEXT,len,(LPARAM)tip_text);
lParam指定緩沖區(qū),wParam指定長(zhǎng)度
當(dāng)TEXTEDIT具有ES_TITLE風(fēng)格時(shí)
EM_SETTITLETEXT設(shè)置標(biāo)題文字
EM_GETTITLETEXT獲取標(biāo)題文字
int len;
char *title_text;
SendMessage(hwndedit,EM_SETTITLETEXT,len,(LPARAM)title_text);
lParam指定字符串,wParam指定長(zhǎng)度
或
int len;
char title_text[len+1];
SendMessage(hwnd,EM_GETTITLETEXT,len,(LPARAM)title_text)
lParam指定緩沖區(qū),wParam指定長(zhǎng)度
編輯框通知碼
編輯框沒(méi)有ES_NOTIFY風(fēng)格
EN_SETFOCUS
EN_KILLFOCUS
EN_CHANGE
EN_ENTER
EN_MAXTEXT
EN_CLICKED
EN_DBLCLK
控件專用函數(shù)
GetNotificationCallback獲取控件的通知消息的回調(diào)函數(shù)
SetNotificationCallback設(shè)置控件的通知消息的回調(diào)函數(shù)
NotifyParentEx發(fā)送控件通知消息
MiniGUI編程--靜態(tài)框
分類: minigui2009-11-04 20:43
靜態(tài)框
以CTRL_STATIC/"static"為類名調(diào)用CreateWindow即可創(chuàng)建
風(fēng)格
普通
SS_SIMPLE
SS_LEFT
SS_CENTER
SS_RIGHT
SS_LEFTNOWORDWRAP
位圖
SS_BITMAP
SS_ICON
dwAddData指定位圖/圖標(biāo)對(duì)象指針
SS_CENTERIMAGE
SS_REALSIZEIMAGE
CreateWindow(CTRL_STATIC,"",WS_CHILD|SS_BITMAP|WS_VISIBLE,IDC_STATIC,280,80,50,50,hwnd,(DWORD)GetSystemBitmap(SYSBMP_CHECKMARK));
CreateWindow(CTRL_STATIC,"",WS_CHILD|SS_ICON|WS_VISIBLE,IDC_STATIC,280,80,50,50,hwnd,(DWORD)GetLargeSystemIcon(IDI_INFOMATION));
CreateWindow(CTRL_STATIC,"",WS_CHILD|SS_BITMAP|SS_CENTERIMAGE|SS_REALSIZEIMAGE|WS_VISIBLE,IDC_STATIC,280,80,50,50,hwnd,(DWORD)GetSystemBitmap(SYSBMP_CHECKMARK));
指定分組框(框架)
SS_GROUPBOX
顏色風(fēng)格
SS_WHITERECT
SS_GRAYRECT
SS_BLACKRECT
SS_WHITEFRAME
SS_BLACKFRAME
SS_GRAYFRAME
通知碼
必須設(shè)置SS_NOTIFY風(fēng)格
單擊STN_CLICKED
雙擊STN_DBLCLK
按鈕
以CTRL_BUTTON/"button"為類我調(diào)用CreateWindow可創(chuàng)建按鈕
默認(rèn)按鈕:BS_DEFPUSHBUTTON
按鈕向父窗口發(fā)送MSG_COMMAND和BN_CLICKED
多行風(fēng)格:BS_MULTILINE
位圖風(fēng)格:BS_BITMAP
圖標(biāo)風(fēng)格:BS_ICON
通過(guò)CreateWindow的dwAddData傳遞位圖/圖標(biāo)對(duì)象的句柄
保持原有大小:BS_REALSIZEIMAGE
復(fù)選框
在按鈕基礎(chǔ)上指定以下兩種風(fēng)格:
BS_CHECKBOX手動(dòng)向控件發(fā)消息設(shè)置
BS_AUTOCHECKBOX自動(dòng)設(shè)置小圓點(diǎn)
BS_3STATE
BS_AUTO3STATE
文字位置:
BS_LEFTTEXT
BS_LEFT
BS_CENTER
BS_RIGHT
BS_TOP
BS_VCENTER
BS_BOTTOM
單選按鈕
風(fēng)格:
BS_RADIOBUTTON
BS_AUTORADIOBUTTON
文本位置:
BS_LEFTTEXT
BS_LEFT
BS_CENTER
BS_RIGHT
BS_TOP
BS_VCENTER
BS_BOTTOM
互斥在第一個(gè)單選鈕按設(shè)置WS_GROUP
按鈕消息
查詢/設(shè)置選中消息BM_GETCHECK/BM_SETCHECK
BM_GETSTATE/BM_SETSTATE
BM_GETIMAGE/BM_SETIMAGE
BM_CLICK
模擬
SendMessage(hwndbtn,BM_SETCHECK,BST_CHECKED,0);
按鈕通知碼:
BS_NOTIFY
/
BN_CLICKED
BN_PUSHED
BN_UNPUSHED
BN_DBLCLK
BN_SETFOCUS
BN_KILLFOCUS
CheckDlgButton
CheckRadioButton
IsDlgButtonChecked
本文來(lái)自CSDN博客,轉(zhuǎn)載請(qǐng)標(biāo)明出處:http://blog.csdn.net/creatory/archive/2007/12/03/1914461.aspx
MiniGUI編程--組合框
分類: minigui2009-11-04 20:39
組合框
以CTRL_COMBOBOX/"combobox"為類名調(diào)用CreateWindow
風(fēng)格CBS->ComboBoxStyle
簡(jiǎn)單組合框CBS_SIMPLE
下拉式組合框CBS_DROPDOWNLIST
在用CreateWindow創(chuàng)建組合框時(shí)用dwAddData參數(shù)指定列表框高度值
hcomb=CreateWindow(CTRL_COMBOBOX,"0",WS_VISIBLE|WS_TABSTOP|CBS_SIMPLE|CBS_SORT,IDC_BOX4,10,100,180,24,parent,100);
//指定dwAddData為100,即簡(jiǎn)單組合框列表框的高度為100
旋轉(zhuǎn)組合框CBS_SPINLIST
箭頭在內(nèi)容的左右風(fēng)格:CBS_SPINARROW_LEFTRIGHT
箭頭在內(nèi)容的上下風(fēng)格:CBS_SPINARROW_TOPBOTTOM
其他風(fēng)格:
CBS_READONLY
CBS_UPPERCASE
CBS_LOWERCASE
CBS_EDITBASELINE
CBS_SORT
CBS_EDITNOBORDER無(wú)邊框
CBS_AUTOFOCUS組合框獲得焦點(diǎn),自動(dòng)定位于編輯框中
旋鈕數(shù)字框
以CBS_AUTOSPIN風(fēng)格創(chuàng)建
自動(dòng)循環(huán)顯示風(fēng)格CBS_AUTOLOOP
組合框消息
CB_ADDSTRING
CB_INSERTSTRING
CB_DELETESTIRNG
CB_FINDSTRING
CB_FINDSTRINGEXACT
CB_GETCOUNT
CB_GETCURSEL
CB_SETCURSEL
CB_RESETCONTENT
CB_GETITEMADDDATA
CB_SETITEMADDDATA
CB_GETITEMHEIGHT
CB_SETITEMHEIGHT
CB_SETSTRINGCMPFUNC
CB_GETLBTEXT
CB_GETLBTEXTLEN
CB_GETCHILDREN
CB_LIMITTEXT
CB_SETEDITSEL
CB_GETEDITSEL
旋鈕組合框消息
CB_SPIN 向前向后wParam控制方向0為下1為上
CB_FASTSPIN? 快速向前向后wParam控制方向0為下1為上
旋鈕數(shù)字框消息
CB_GETSPINRNAGE 獲得可取的最大值和最小值
CB_SETSPINRANGE 設(shè)置可取的最大值和最小值
CB_SETSPINVALUE 設(shè)置編輯框當(dāng)前值
CB_GETSPINVALUE 獲得編輯框當(dāng)前值
組合框通知碼
CBN->ComboBoxNotify
CBN_ERRSPACE
CBN_SELCHANGE
CBN_EDITCHANGE
CBN_DBLCLK
CBN_CLICKED
CBN_SETFOCUS
CBN_KILLFOCUS
CBN_DROPDOWN
CBN_CLOSEUP
CBN_SELENDOK
CBN_SELENDCANCEL
菜單按鈕
以CTRL_MENUBUTTON為類名調(diào)用CreateWindow
一般風(fēng)格:WS_CHILD|WS_VISIBLE|MBS_SORT
MBS->MenuButtonStyle
MBS_SORT
MBS_LEFTARROW
MBS_NOBUTTON
MBS_ALIGNLEFT
MBS_ALIGNRIGHT
MBS_ALIGNCENTER
向菜單按鈕添加條目
使用MBM_ADDITEM消息和MENUBUTTONITEM結(jié)構(gòu)
MENUBUTTONITEM mbi;
mbi.text="item one";
mbi.bmp=NULL;
mbi.data=0;
pos=SendMessage(hmbtnwnd,MBM_ADDITEM,-1,(LPARAM)&mbi);
從菜單按鈕刪除條目
MBM_DELITEM
SendMessage(hMbtnwnd,MBM_DELITEM,index,0);
刪除所有條目
MBM_RESETCTRL
SendMessage(hMbtnwnd,MBM_RESETCTRL,0,0);
設(shè)置當(dāng)前選中條目
MBM_SETCURITEM
SendMessage(hMbtnwnd,MBM_SETCURITEM,index,0);
獲得當(dāng)前選中條目
MBM_GETCURITEM
index=SendMessage(hMbtnwnd,MBM_GETCURITEM,0,0);
獲取條目數(shù)據(jù)
MBM_GETITEMDATA wParam指定索引值,lParam指向一個(gè)MENUBUTTONITEM結(jié)構(gòu)的指針對(duì)性
設(shè)置條目數(shù)據(jù)
MBM_SETITEMDATA
which指定要獲取的數(shù)據(jù)項(xiàng)
MB_WHICH_TEXT
MB_WHICH_BMP
MB_WHICH_ATTDATA
MENUBUTTONITEM mbi;
mbi.which=MB_WHICH_TEXT|MB_WHICH_ATTDATA;
mbi.text="newtext";
mbi.data=1;
SendMessage(menubtn,MBM_SETITEMDATA,0,(LPARAM)&mbi);
通知消息:
MBN->MenuButtonNotify
MBN_ERRSPACE
MBN_SELECTED
MBN_CHANGED
MBN_STARTMENU
MBN_ENDMENU
進(jìn)度條
以CTRL_PROGRESSBAR為類名調(diào)用CreateWindow創(chuàng)建
風(fēng)格:PBS->ProgressBarStyle
PBS_NOTIFY使進(jìn)度條產(chǎn)生通知消息
PBS_VERTICAL豎直顯示進(jìn)度條
通用風(fēng)格:
WS_CHILD|WS_VISIBLE|PBS_NOTIFY
進(jìn)度條設(shè)置
PBM->ProgressBarModify
設(shè)置范圍
PBM_SETRANGE
SendMessage(hwndpb,PBM_SETRANGE,min,max);
設(shè)置步長(zhǎng)
PBM_SETSTEP
SendMessage(hwndpb,PBM_SETSTEP,5,0);
設(shè)置當(dāng)前進(jìn)度
PBM_SETPOS
SendMessage(hwndpb,PBM_SETPOS,50,0);
在當(dāng)前進(jìn)度基礎(chǔ)上偏移
PBM_DELTAPOS
SendMessage(hwndpb,PBM_DELTAPOS,10,0);
前進(jìn)一個(gè)步進(jìn)值
PBM_STEPIT
SendMessage(hwndpb,PBM_STEPIT,0,0);
進(jìn)度條通知碼
指定PBS_NOTIFY風(fēng)格
PBN_REACHMAX
PBN_REACHMIN
滑塊
以CTRL_TRACKBAR為類名調(diào)用CreateWindow
通用風(fēng)格WS_CHILD|WS_VISIBLE|TBS_NOTIFY
豎直滑塊TBS_VERTICAL
TBS_TIP
TBS_NOTICK
TBS_BORDER
滑塊消息
TBM_SETRANGE
TBM_GETMIN
TBM_GETMAX
TBM_SETMIN
TBM_SETMAX
TBM_SETLINESIZE
TBM_GETLINESIZE
TBM_SETPAGESIZE
TBM_GETPAGESIZE
TBM_SETPOS
TBM_GETPOS
TBM_SETTICKFREQ
TBM_SETTIP
TBM_GETTIP
滑塊通知碼
指定TBS_NOTIFY風(fēng)格
TBN_CHANGE
TBN_REACHMAX
TBN_REACHMIN
工具欄
CTRL_TOOLBAR
CTRL_NEWTOOLBAR
CTRL_COOLBAR
以CTRL_NEWTOOLBAR為類名調(diào)用CreateWindow創(chuàng)建
創(chuàng)建工具欄
填充NTBINFO結(jié)構(gòu)賦給CreateWindow的dwAddData能數(shù)
NTBINFO->NewToolBarINFO
成員
image
nr_cells
nr_cols
w_cell
h_cell
風(fēng)格
NTBS_HORIZONTAL
NTBS_VERTICAL
NTBS_MULTLINE
NTBS_WITHTEXT
NTBS_TEXTRIGHT
NTBS_DRAWSTATES
NTBS_DRAWSEPARATOR
添加工具項(xiàng)
發(fā)送NTBM_ADDITEM消息傳遞NTBITEMINFO結(jié)構(gòu)
成員
which :NTBM_GETTITEM/NTBM_SETITEM
flags :NTBIF_PUSHBUTTON/NTBIF_CHECKBUTTON/NTBIF_HOTSPOTBUTTON/NTBIF_NEWLINE
id??? :按鈕標(biāo)識(shí)符
text? :指定NTBS_WITHTEXT風(fēng)格時(shí)顯示的文本
tip?? :保留
bmp_cell
hotspot_proc
rc_hotspot
add_data
MiniGUI消息投遞方式
分類: minigui2009-11-04 20:38
消息發(fā)送方式:
1.將消息投遞到一個(gè)先進(jìn)先出隊(duì)列中
2.直接把消息發(fā)給窗口過(guò)程
投遞到隊(duì)列中的消息主要有:
鍵盤(pán)和鼠標(biāo)消息MSG_LBUTTONDOWN,MSG_MOUSEMOVE,MSG_KEYDOWN,MSG_CHAR
定時(shí)器消息MSG_TIMER
繪制消息MSG_PAINT
退出消息MSG_QUIT
可以用HavePendingMessage函數(shù)檢查消息隊(duì)列中是否有消息而不取出的消息
BOOL GUIAPI HavePendingMessage(HWND hMainWnd);
直接發(fā)送到窗口過(guò)程的消息一般用于通知窗口完成一些需要立即處理的事件,如MSG_ERASEBKGND消息
消息的處理
一般通過(guò)一個(gè)消息循環(huán)來(lái)處理消息隊(duì)列中的消息
GetMessage從消息隊(duì)列中取出消息
TranslateMessage翻譯消息
DispatchMessage發(fā)送消息
如下:
MSG msg;
HWND hMainWnd;
MAINWINCREATE CreateInfo;
InitCreateInfo(&CreateInfo);
hMainWnd=CreateMainWindow(&CreateInfo);
if(hMainWnd==HWND_INVALID)
return -1;
while(GetMessage(&msg,hMainWnd))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
在Thread中當(dāng)要求等待消息立即返回以處理其他事務(wù)時(shí)可以使用HavePendingMessage
do
{
ReadMasterPty(pConInfo);
if(pConInfo->terminate)
break;
while(HavePendingMessage(hMainWnd))
{
if(!GetMessage(&msg,hMainWnd))
break;
DispatchMessage(&msg);
}
}while(true);
窗口過(guò)程是一個(gè)特定類型的函數(shù),用于接收和處理所有發(fā)送到該窗口的消息
每個(gè)控件類也有一個(gè)窗口過(guò)程,屬于同一控件類的所有控件共用同一個(gè)窗口過(guò)程處理消息
如果窗口過(guò)程不處理某些消息一般把該消息傳給系統(tǒng)進(jìn)行默認(rèn)處理
int DefaultMainWinProc(HWND hwnd,int message,WPARAM wParam,LPARAM lParam);
對(duì)話框缺省消息處理函數(shù)
int DefaultDialogProc(HWND hwnd,int message,WPARAM wParam,LPARAM lParam);
控件窗口缺省消息處理函數(shù)
int DefaultControlProc(HWND hwnd,int message,WPARAM wParam,LPARAM lParam);
投遞:把一條消息復(fù)制到消息隊(duì)列中
發(fā)送: 直接把消息發(fā)送到窗口過(guò)程函數(shù)
消息處理函數(shù):
PostMessage:將消息放到消息隊(duì)列后立即返回,用于發(fā)送非關(guān)鍵性消息,受消息緩沖區(qū)限制
SendMessage:將消息發(fā)送到窗口過(guò)程,等待處理完后返回
SendNotifyMessage:同PostMessage,采用鏈表處理,不受緩沖區(qū)限制,一般用于從控件向父窗口發(fā)送“通知消息”
PostQuitMessage:將MSG_QUIT消息投遞到消息隊(duì)列中
將指定消息廣播給桌面的所有主窗口:
int GUIAPI BroadcastMessage(int iMsg,WPARAM wParam,LPARAM lParam);
丟棄消息隊(duì)列中所有消息并返回個(gè)數(shù)
int GUIAPI ThrowAwayMessages(HWND pMainWnd);
等待一有消息就返回
BOOL GUIAPI WaitMessage(PMSG pMsg,HWND hMainWnd);
MiniGUI消息大全:
1.MSG_DESTROY
調(diào)用DestroyMainWindow/DestroyWindow時(shí)發(fā)送到窗口過(guò)程中
例:程序在MSG_DESTROY消息中銷毀被托管主窗口的位圖字體等資料
case MSG_DESTROY:
???? DestroyIocn(icon1);
???? DestroyIocn(icon2);
???? DestroyAllControls(hWnd);
???? return 0;
例:被托管主窗口響應(yīng)MSG_CLOSE消息
case MSG_CLOSE:
???? DestroyMainWindow(hWnd);
???? MainWindowCleanup(hWnd);
???? return 0;
2.MSG_CLOSE
點(diǎn)擊“X”按鈕時(shí)向窗口過(guò)程發(fā)送該消息,程序該在響應(yīng)該消息時(shí)調(diào)用DestroyMainWindow銷毀主窗口并用PostQuitMessage向隊(duì)列中投放MSG_QUIT消息
3.MSG_PAINT
窗口進(jìn)行重繪時(shí)該消息被發(fā)送到窗口過(guò)程
窗口在初始顯示時(shí)
從隱藏狀態(tài)變?yōu)轱@示狀態(tài)
從部分不可見(jiàn)到可見(jiàn)狀態(tài)
調(diào)用InvalidateRect時(shí)
窗口過(guò)程在收到該消息時(shí)應(yīng)該對(duì)窗口進(jìn)行界面維護(hù)
case MSG_PAINT:
?HDC hdc;
?hdc=BeginPaint(hwnd);
?...
?EndPaint(hwnd,hdc);
?return 0;
程序處理完后要直接返回,不應(yīng)該再傳遞給默認(rèn)窗口過(guò)程處理
4.MSG_ERASEBKGND
需要清除窗口背景時(shí)發(fā)送該消息
InvalidateRect/UpdateWindow并為bErase傳遞TRUE時(shí)
如果在MSG_PAINT消息時(shí)重繪所有的窗口客戶區(qū)應(yīng)忽略該消息
case MSG_ERASEBKGND:
?return 0;
在窗口背景上填充圖片:
case MSG_ERASEBKGND:
HDC hdc=(HDC)wParam;
const RECt *clip=(const RECT*)lParam;
BOOL fGetDC=FALSE;
RECT rcTemp;
if(hdc==0)
{
hdc=GetClientDC(hwnd);
fGetDC=TRUE;
}
if(clip)
{
rcTemp=*clip;
ScreenToClient(hDlg,&rcTemp.left,&rcTemp.top);
ScreenToClient(hDlg,&rcTemp.right,&rcTemp.bottom);
IncludeClipRect(hdc,&rcTemp);
}
FillBoxWithBitmap(hdc,0,0,0,0,&bmp_bkgnd);
if(fGetDC)
ReleaseDC(hdc);
return 0;
5.MSG_FONTCHANGED
調(diào)用SetWindowFont改變了默認(rèn)字體后將引發(fā)該消息
窗口過(guò)程需要處理以便反映出新的字體設(shè)置
如編輯框就要處理并重繪自己:
case MSG_FONTCHANGED:
{
sled=(PSLEDITDATA)GetWindowAdditionalData2(hwnd);
sled->startpos=0;
sled->editpos=0;
edtGetLineInfo(hwnd,sled);
DestroyCaret(hwnd);
CreateCaret(hwnd,NULL,1,GetWindowFont(hwnd)->size);
SetCaretPos(hwnd,sled->leftMargin,sled->topMargin);
InvalidateRect(hwnd,NULL,TRUE);
return 0;
}
6.MSG_FONTCHANGING
當(dāng)調(diào)用SetWindowFont改變默認(rèn)字體時(shí)引發(fā)該消息
通常窗口過(guò)程將此消息傳遞給默認(rèn)窗口過(guò)程處理
如果窗口不允許用戶改變字體可以加以截獲該消息將返回非零值
case MSG_FONTCHANGING:
???? return -1;
7.MSG_CREATE
窗口成功創(chuàng)建并添加到窗口管理器中時(shí)引發(fā)該消息
8.MSG_SIZECHANGED
窗口尺寸變化時(shí)發(fā)生,wParam包含窗口大小,lParam用于保存窗口客戶區(qū)大小的RECT指針
case MSG_SIZECHANGED:
RECT *rcClient=(RECT*)lParam;
rcClient->right=rcClient->left+_WIDTH;
rcClient->bottom=rcClient->top+_HEIGHT;
return 0;
9.MSG_SIZECHANGING
窗口尺寸發(fā)生變化時(shí)引發(fā)該消息,用于確定窗口大小
wParam包含預(yù)期窗口尺寸值,lParam用于保存結(jié)果值
case MSG_SIZECHANGING:
?memcpy((PRECT)lParam,(PRECT)wParam,sizeof(RECT));
?return 0;
可以截獲該消息使創(chuàng)建的窗口位于指定的位置或具有固定的大小
case MSG_SIZECHANGING:
const RECT *rcExpect=(const RECT*)wParam;
RECT*rcResult=(RECT*)lParam;
rcResult->left=rcExcept->left;
rcResult->top=rcExcept->top;
return 0;
10.MSG_NCCREATE
建立主窗口過(guò)程中引發(fā), 此時(shí)窗口對(duì)象尚未建立,不能使用GetDC等函數(shù)
必須在此消息的處理中進(jìn)行輸入法窗口注冊(cè)
case MSG_NCCREATE:
if(hz_input_init())
SendMessage(HWND_DESKTOP,MSG_IME_REGISTER,(WPARAM)hwnd,0);
else
return -1;
break;
MiniGUI通用窗口操作函數(shù),可用于主窗口和控件
UpdateWindow? 立即更新某個(gè)窗口
ShowWindow??? 顯示/隱藏某個(gè)窗口
IsWindowVisible 判斷某個(gè)窗口是否可見(jiàn)
EnableWindow 激活/禁止某個(gè)窗口
IsWindowEnabled 判斷某個(gè)窗口是否可用
GetClientRect 取得客戶區(qū)矩形
GetWindowRect 取得窗口矩形
GetWindowBkColor 取得窗口背景色
SetWindowBkColor 設(shè)置窗口背景色
GetWindowFont 取得窗口默認(rèn)字體
SetWindowFont 設(shè)置窗口默認(rèn)字體
GetWindowCursor 取得窗口光標(biāo)
SetWindowCursor 設(shè)置窗口光標(biāo)
GetWindowStyle 取得窗口風(fēng)格
GetWindowExStyle 取得窗口擴(kuò)展風(fēng)格
GetFocusChild 取得有輸入焦點(diǎn)的子窗口
SetFocusChild 設(shè)置焦點(diǎn)子窗口
GetWindowCallbackProc 取得窗口過(guò)程函數(shù)
SetWindowCallbackProc 設(shè)置窗口過(guò)程函數(shù)
GetWindowAdditionalData 取得窗口附加數(shù)據(jù)一
SetWindooAdditionalData 設(shè)置窗口附加數(shù)據(jù)一
GetWindowAdditionalData2
SetWindowAdditionalData2
GetWindowCaption 獲取窗口標(biāo)題
SetWindowCaption 設(shè)置窗口標(biāo)題
InvalidateRect 使窗口給定矩形區(qū)域無(wú)效,將引發(fā)窗口重繪
GetUpdateRect 獲取窗口當(dāng)前無(wú)效區(qū)域外包矩形
ClientToScreen 客戶區(qū)坐標(biāo)轉(zhuǎn)換為屏幕坐標(biāo)
ScreenToClient 屏幕坐標(biāo)轉(zhuǎn)換為客戶區(qū)坐標(biāo)
WindowToScreen窗口坐標(biāo)轉(zhuǎn)換為屏幕坐標(biāo)
ScreenToWindow
IsMainWindow判斷給定窗口是否為主窗口
IsControl判斷給定窗口控件
IsDialog斷送給定窗口是否為對(duì)話框
GetParent獲取父窗口句柄,主窗口父窗口為HWND_DESKTOP
GetMainWindowHandle獲取某個(gè)窗口的主窗口句柄
GetNextChild取得下一個(gè)子窗口
GetNextMainWindow取得下一個(gè)主窗口句柄
GetHosting獲取某個(gè)窗口的托管窗口
GetFirstHosted 取得某個(gè)主窗口的第一個(gè)被托管窗口
GetNextHosted 獲取下一人被托管窗口
GetActiveWindow 取得當(dāng)前活動(dòng)窗口
SetActiveWindow 設(shè)置當(dāng)前活動(dòng)窗口
GetCapture獲取當(dāng)前捕獲鼠標(biāo)的窗口
SetCapture捕獲
ReleaseCapture釋放
MoveWindow移動(dòng)/改變窗口大小
ScrollWindow滾動(dòng)窗口客戶區(qū)內(nèi)容
創(chuàng)建簡(jiǎn)單的控件
調(diào)用CreateWindow直接創(chuàng)建子窗口
或使用對(duì)話框模板創(chuàng)建一類控件
模板結(jié)構(gòu)<minigui/window.h>中定義
用于定義控件
typedef struct
{
char *class_name; //控件類
DWORD dwStyle; //風(fēng)格
int x,y,w,h; //控件在對(duì)話框中的位置
int id; //控件ID
const char *caption; //控件標(biāo)題
DWORD dwAddData; //附加數(shù)據(jù)
DWORD dwExStyle; //擴(kuò)展風(fēng)格
}CTRLDATA;
typedef CTRLDATA *PCTRLDATA;
用于定義對(duì)話框模板
typedef struct
{
DWORD dwStyle; //對(duì)話框風(fēng)格
DWORD dwExStyle; //對(duì)話框擴(kuò)展風(fēng)格
int x,y,w,h; //對(duì)話框位置
const char*caption; //對(duì)話框標(biāo)題
HICON hIcon; //對(duì)話框圖標(biāo)
HMENU hMenu; //對(duì)話框菜單
int controllnr; //控件數(shù)目
PCTRLDATA controls; //指同控件數(shù)組的指針
DWORD dwAddData;? //附加數(shù)據(jù),必須為0
}DLGTEMPLATE;
typedef DLGTEMPLATE *PDLGTEMPLATE;
結(jié)構(gòu)CTRLDATA用于定義控件,DLGTEMPLATE用于定義對(duì)話框本身
程序應(yīng)首先用CTRLDATA定義對(duì)話框中所有的控件并用數(shù)組表示
控件在數(shù)組中的順序就是用戶按TAB時(shí)的切換順序
然后定義對(duì)話框
指定對(duì)話框中的控件數(shù)目
并指定DLGTEMPLATE->controls指向控件數(shù)組
例:
static DLGTEMPLATE DlgInitProcess=
{
WS_BORDER|WS_CAPTION,
WS_EX_NONE,
120,150,400,130,
"VAM-CNC正在初始化",
0,0,
3,NULL,
0
};
static CTRLDATA CtrlInitProcess=
{
{"static",
WS_VISIBLE|SS_SIMPLE,
10,10,380,16,
IDC_PROMPTINFO,
"正在...",
0
},
{
"processbar",
WS_VISIBLE,
10,40,380,20,
IDC_PROCESS,
NULL,
0
},
{
"button",
WS_TABSTOP|WS_VISIBLE|BS_DEFPUSHBUTTON,
170,70,60,25,
ID_OK,
"確定",
0
}
};
應(yīng)盡量將定義的對(duì)話框模板數(shù)據(jù)接口定義為static類型,使其僅在該文件中有效,以免造成錯(cuò)誤
MiniGUI對(duì)話框編程
分類: minigui2009-11-04 20:38
定義對(duì)話框模板后,再定義對(duì)話框回調(diào)函數(shù)并調(diào)用DialogBoxIndirectParam建立對(duì)話框
例:
static int InitDialogBoxProc(HWND hDlg,int message,WPARAM wParam,LPARAM lParam)
{
switch(message)
{
case MSG_INITDIALOG:
return 1;
case MSG_COMMAND:
switch(wParam)
{
case IDOK:
case IDCANCEL:
EndDialog(hDlg,wParam);
break;
}
break;
}
return DefaultDialogProc(hDlg,message,wParam,lParam);
}
static void InitDialogBox(HWND hWnd)
{
DlgInitProcess.controls=CtrlInitProcess;
DialogBoxIndirectParam(&DlgInitProcess,hWnd,InitDialogBoxProc,0L);
}
創(chuàng)建對(duì)話框函數(shù)
int GUIAPI DialogBoxIndirectParam(PDLGTEMPLATE pDlgTemplate,HWND hOwner,WNDPROC DlgProc,LPARAM lParam);
參數(shù):對(duì)話框模板,托管主窗口句柄,回調(diào)函數(shù)地址,附加參數(shù)值
BOOL GUIAPI EndDialog(HWND hDlg,int endcode);
結(jié)束對(duì)話框過(guò)程
void GUIAPI DestroyAllControls(HWND hDlg);
銷毀對(duì)話框中所有子控件
創(chuàng)建非模態(tài)對(duì)話框
HWND GUIAPI CreateMainWindowIndirect(PDLGTEMPLATE pDlgTemplate,HWND hOwner,WNDPROC WndProc);
BOOL GUIAPI DestroyMainWindowIndirect(HWND hMainWin);
例:
static int InitWindowProc(HWND hDlg,int message,WPARAM wParam,LPARAM lParam)
{
switch(message)
{
case MSG_COMMAND:
swtich(wParam)
{
case IDOK:
case IDCANCEL:
DestroyMainWindowIndirect(hWnd);
break;
}
break;
}
return DefaultWindowProc(hDlg,message,wParam,lParam);
}
...
{
HWND hwnd;
MSG msg;
DlgInitProcess.controls=CtrlInitProcess;
hwnd=CreateMainWindowIndirect(&DlgInitProcess,HWND_DESKTOP,InitWindowProc);
if(hwnd==HWND_INVALID)
return -1;
while(GetMessage(&msg,hwnd))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
對(duì)話框控件風(fēng)格
WS_GROUP? 成為同組控件頭一個(gè)
WS_TABSTOP 支持TAB切換
對(duì)話框操作函數(shù):
DestroyAllControls
GetDlgCtrlID
GetDlgItem
GetDlgItemInt
SetDlgItemInt
GetDlgItemText
GetDlgItemText2
SetDlgItemText
GetNextDlgGroupItem
GetNextDlgGroupItem
SendDlgItemMessage
CheckDlgButton
CheckRadioButton
IsDlgButtonChecked
GetDlgDefPushButton
MinGUI預(yù)定義控件類:
"static" CTRL_STATIC
"button" CTRL_BUTTON
"sledit" CTRL_SLEDIT (Single Line)
"mledit" CTRL_MLEDIT (Multi Line)
"textbox" CTRL_TEXTBOX
"listbox" CTRL_LISTBOX
"progressbar" CTRL_PROGRESSBAR
"trackbar" CTRL_TRACKBAR
"combobox" CTRL_COMBOBOX
"newtoolbar" CTRL_NEWTOOLBAR
"menubutton" CTRL_MENUBUTTON
"propsheet" CTRL_PROPSHEET
"ScrollWnd" CTRL_SCROLLWND
"ScrollView" CTRL_SCROLLVIEW
"treeview" CTRL_TREEVIEW
"listview" CTRL_LISTVIEW
"MonthCalendar" CTRL_MONTHCALENDAR
"SpinBox" CTRL_SPINBOX
"CoolBar" CTRL_COOLBAR
"IconView" CTRL_ICONVIEW
"gridview" CTRL_GRIDVIEW
"Animation" CTRL_ANIMATION
調(diào)用CreateWindow/CreateWindowEx創(chuàng)建預(yù)定義控件類的實(shí)例
HWND GUIAPI CreateWindowEx(const char*spClassName,const char*spCaption,DWORD dwStyle,DWORD dwExStyle,int id,int x,int y,int w,int h,HWND hParentWnd,DWORD dwAddData);
BOOL GUIAPI DestroyWindow(HWND hWnd);
#define CreateWindow(class_name,caption,style,id,x,y,w,h,parent,add_data) CreateWindowEx(class_name,caption,style,0,id,x,y,w,h,parent,add_data)?
參數(shù):
控件類,標(biāo)題,風(fēng)格,標(biāo)識(shí)符,位置,父窗口,附加數(shù)據(jù)
例:
#define IDC_STATIC1 100
#define IDC_STATIC2 150
#define BUTTON1 110
#define BUTTON2 120
#define EDIT1 130
#define EDIT2 140
//創(chuàng)建一個(gè)靜態(tài)框
hStaticWnd1=CreateWindow(CTRL_STATIC,"This is a static control",WS_CHILD|WS_VISIBLE|WS_BORDER|SS_NOTIFY|SS_SIMPLE,
IDC_STATIC1,
10,10,180,300,
hWnd,
0);
//在hStaticWnd1中創(chuàng)建兩個(gè)按鈕
hButton1=CreateWindow(CTRL_BUTTON,"button1",
WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,
IDC_BUTTON1,
20,20,80,20,
hStaticWnd1,
0);
hButton2=CreateWindow(CTRL_BUTTON,"button2",
WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,
IDC_BUTTON2,
20,50,80,20,
hStaticWnd1,
0);
//在hStaticWnd1中創(chuàng)建一個(gè)編輯框
hEdit1=CreateWindow(CTRL_EDIT,"edit box 1",
WS_CHILD|WS_VISIBLE|WS_BORDER,
IDC_EDIT1,
20,80,100,24,
hStaticWnd1,
0);
//在hStaticWnd1中創(chuàng)建一個(gè)靜態(tài)框
hStaticWnd2=CreateWindow(CTRL_STAIC,"This is a child static control",
WS_CHILD|WS_VISIBLE|WS_BORDER|SS_NOTIFY|SS_SIMPLE,
IDC_STATIC2,
20,110,100,50,
hStaticWnd1,
0);
//在hStaticWnd2中創(chuàng)建一個(gè)編輯框(為hStaticWnd1的孫窗口)
hEdit2=CreateWindow(CTRL_EDIT,"edit box 2",
WS_CHILD|WS_VISIBLE|WS_BORDER,
IDC_EDIT2,
0,20,100,24,
hStaticWnd2,
0);
控件內(nèi)部發(fā)生事件時(shí),向父窗口發(fā)送MSG_COMMAND消息
該消息的wParam由子窗口標(biāo)識(shí)符和通知碼組成
lParam含有發(fā)出通知消息的控件句柄
如:
編輯框向父窗口發(fā)送EN_CHANGE消息
switch(message)
{
case MSG_COMMAND:
int id=LOWORD(wParam);
int nc=HIWORD(wParam);
if(id==ID_MYEDIT&&nc==EN_CHANGE)
{...
}
break;
}
設(shè)置控件通知消息回調(diào)函數(shù)
SetNotificationCallback
例:
編輯框的回調(diào)函數(shù)
static void notif_proc(HWND hwnd,int id,int nc,DWORD add_data)
當(dāng)對(duì)話框中有多個(gè)控件時(shí)要分別定義每一個(gè)控件的回調(diào)函數(shù)
并在對(duì)話框初始話消息時(shí)設(shè)置
case MSG_INITDIALOG:
SetNotificationCallback(GetDlgItem(hDlg,IDC_SIZE_MM),notif_proc);
控件子類化,定制特殊的控件
#define IDC_CTRL1 100
#define IDC_CTRL2? 110
#define IDC_CTRL3? 120
#define IDC_CTRL4? 130
#define MY_ES_DIGIT_ONLY 0x0001
#define MY_ES_ALPHA_ONLY 0x0002
staic WNDPROC old_edit_proc;
學(xué)習(xí)MiniGUI之窗口創(chuàng)建篇
分類: minigui2009-11-04 12:56
最近在學(xué)習(xí)MiniGui,將一些分析的結(jié)果貼出來(lái)供大家參考,同時(shí)歡迎大家的指正。
圖形編程中,窗口是一個(gè)重要的概念,窗口其實(shí)是一個(gè)矩形框,應(yīng)用程序可以使用其從而達(dá)到輸出結(jié)果和接受用戶輸入的效果。窗口系統(tǒng)(Window System)界于操作系統(tǒng)層次之上,它是一個(gè)軟件系統(tǒng),負(fù)責(zé)把顯示屏幕分隔為不同的部分來(lái)幫助用戶管理和控制不同的顯示環(huán)境,它提供基于窗口的工作模式。在Linux上面,X就是一個(gè)典型的窗口系統(tǒng)吧。
?? 在MiniGui中有三種窗口類型:主窗口,對(duì)話框和控件窗口。主窗口作為應(yīng)用程序的主界面或開(kāi)始界面。子窗口通常是控件窗口,也可以是自定義窗口類,這里的控件窗口說(shuō)白了就是一些窗口上面的控件,比如按鈕,編輯框等。對(duì)話框其實(shí)就是主窗口,只不過(guò)一般為了完成特殊用途,所以在此加以區(qū)分。
?? 下面我們一起來(lái)看看這三種窗口類型的創(chuàng)建吧。首先看CreateMainWindow函數(shù),它創(chuàng)建一個(gè)主窗口:由于代碼比較長(zhǎng),這里就不全部貼出了,主要是說(shuō)說(shuō)關(guān)鍵的部分。
?? CreateMainWindow函數(shù)通過(guò)接受PMAINWINCREATE類型的參數(shù)而創(chuàng)建一個(gè)窗口,并返回其句柄。關(guān)于PMAINWINCREATE結(jié)構(gòu)的具體成員變量,大家可以去查看源碼。下面主要對(duì)函數(shù)內(nèi)部做個(gè)簡(jiǎn)單介紹。
1.?????? 聲明一個(gè)PMAINWIN類型,并分配空間,該變量用來(lái)存放創(chuàng)建的主窗口的信息
2.?????? 說(shuō)下面的代碼之前,先說(shuō)說(shuō)托管(Hosting)窗口和被托管(Hosted)窗口吧。我們知道MiniGui內(nèi)部實(shí)現(xiàn)了消息機(jī)制,即當(dāng)有鍵盤(pán)輸入事件發(fā)生時(shí),就往消息隊(duì)列中發(fā)送鍵盤(pán)消息,而一般是主窗口會(huì)不停的從消息隊(duì)列中取出消息來(lái)處理,或者自己響應(yīng),或者忽略,或者派發(fā)給其他的窗口。那么這里就有一個(gè)問(wèn)題,消息隊(duì)列是每個(gè)主窗口都有一個(gè)呢,還是所有的主窗口都使用同一個(gè)消息隊(duì)列?在MiniGui中有個(gè)特殊的主窗口HWND_DESKTOP,它是所有窗口的父窗口,直觀的說(shuō)就是整個(gè)桌面的窗口。當(dāng)一個(gè)主窗口在創(chuàng)建的時(shí)候,可以指定新建一個(gè)消息隊(duì)列,也可以使用別的主窗口的消息隊(duì)列,如果是后者,假設(shè)主窗口A在創(chuàng)建時(shí)指定使用主窗口B的消息隊(duì)列,那么A就被稱為被托管窗口,而B(niǎo)則被稱為托管窗口。所以很明顯CreateInfo.hHosting就是用來(lái)指明托管窗口的。來(lái)看下面的代碼,這里對(duì)MiniGUI的兩種運(yùn)行模式進(jìn)行了區(qū)分,1-15行是MiniGUI-Threads模式,在這種模式下,如果托管窗口為HWND_DESKTOP,則新建一個(gè)消息隊(duì)列(2-12行);如果托管窗口不為HWND_DESKTOP,則返回hHosting所在的主窗口的消息隊(duì)列。16行是非MiniGUI-Threads模式下,僅僅表明新的主窗口使用HWND_DESKTOP的消息隊(duì)列,這里其實(shí)忽略了pHosting參數(shù)。
1: #ifndef _LITE_VERSION
2:?? if (pCreateInfo->hHosting == HWND_DESKTOP) {
3:??????? // Create message queue for this new main window.
4:??????? if( !(pWin->pMessages = malloc(sizeof(MSGQUEUE))) ) {
5:??????????? free(pWin);
6:??????????? return HWND_INVALID;
7:??????? }
8:?????
9:??????? // Init message queue.
10:??????? if (!InitMsgQueue(pWin->pMessages, 0))
11:??????????? goto err;
12:??? }
13:??? else
14:??????? pWin->pMessages = GetMsgQueue (pCreateInfo->hHosting);
15: #else
16:??????? pWin->pMessages = &__mg_dsk_msgs;
17: #endif
?
3.?????? 下面的幾行是對(duì)pWin進(jìn)行初始化的操作,第1行賦值消息處理回調(diào)函數(shù)。第9行,初始化pZorderNode成員
1:??? pWin->MainWindowProc = pCreateInfo->MainWindowProc;
2:??? pWin->iBkColor??? = pCreateInfo->iBkColor;
3:
4:??? pWin->pCaretInfo = NULL;
5:
6:??? pWin->dwAddData = pCreateInfo->dwAddData;
7:??? pWin->dwAddData2 = 0;
8:
9:??? if ( !( pWin->pZOrderNode = malloc (sizeof(ZORDERNODE))) )
10:??????? goto err;
?
4.?????? 初始化結(jié)束之后,就開(kāi)始發(fā)送消息通知自身來(lái)真正的繪制窗口了。1-4行發(fā)送本窗口的MSG_SIZECHANGING和MSG_CHANGESIZE消息,會(huì)調(diào)用本窗口消息回調(diào)函數(shù)中的相應(yīng)處理部分。第6行是發(fā)送MSG_ADDNEWMAINWIN消息給HWND_DESKTOP窗口,HWND_DESKTOP窗口主要負(fù)責(zé)初始化Clip區(qū)和Invalid區(qū),并且把當(dāng)前窗口添加到sg_MainWinZOrder鏈表里,這個(gè)鏈表記錄的是所有窗口的疊加順序,在顯示和隱藏窗口的時(shí)候,疊加順序很重要,它會(huì)決定屏幕上哪些窗口會(huì)受影響而需要重繪。第9行發(fā)送MSG_CREATE消息給窗口,窗口接受到此消息一般進(jìn)行子窗口的初始化和創(chuàng)建,如果創(chuàng)建失敗了,則通知HWND_DESKTOP窗口銷毀該主窗口。
1:? SendMessage ((HWND)pWin, MSG_SIZECHANGING,
2:??????????????? (WPARAM)&pCreateInfo->lx, (LPARAM)&pWin->left);
3:? SendMessage ((HWND)pWin, MSG_CHANGESIZE,
4:??????????????? (WPARAM)&pWin->left, 0);
5:
6:? SendMessage (HWND_DESKTOP, MSG_ADDNEWMAINWIN,
7:??????????????? (WPARAM) pWin, (LPARAM) pWin->pZOrderNode);
8:
9:? if (SendMessage ((HWND)pWin, MSG_CREATE, 0, (LPARAM)pCreateInfo)) {
10:??????? SendMessage(HWND_DESKTOP,
11:????????????????????? MSG_REMOVEMAINWIN, (WPARAM)pWin, 0);
12:??????? goto err;
13: }
?
?
接下來(lái)我們看對(duì)話框的創(chuàng)建過(guò)程,對(duì)話框分為模態(tài)和非模態(tài)對(duì)話框。非模態(tài)對(duì)話框的創(chuàng)建過(guò)程和主窗口的創(chuàng)建過(guò)程差不多,其中也調(diào)用了CreateMainWindow函數(shù),之后還調(diào)用了CreateWindowEx創(chuàng)建對(duì)話框上的控件。模態(tài)對(duì)話框就是顯示之后,用戶不能再切換到其他主窗口進(jìn)行工作的對(duì)話框,而只能在關(guān)閉之后,才能使用其他的主窗口,通過(guò)DialogBoxIndirectParam創(chuàng)建,一開(kāi)始的步驟與非模態(tài)對(duì)話框類似,以下的代碼是其不同的部分:第7行,hOwner是待創(chuàng)建對(duì)話框的托管主窗口,這里其實(shí)是把它disable掉了。第11行是處理MSG_INITDIALOG消息。第18-21行,是消息處理的循環(huán)機(jī)制,這里可以看到這就是為什么模態(tài)對(duì)話框一定要等到關(guān)閉之后,才可以使用其它的主窗口,這里還需要注意一點(diǎn),由于是從對(duì)話框的托管主窗口是HWND_DESKTOP窗口,因此他們共用一個(gè)消息隊(duì)列,此時(shí),對(duì)話框可能接受到發(fā)送給托管主窗口的消息,而由于在第7行中已經(jīng)將托管主窗口的dwStyle設(shè)置為WS_DISABLE了,因此在這些消息處理流程里面可以做相應(yīng)的處理(例如當(dāng)窗口被設(shè)置為WS_DISABLE時(shí),忽略該消息)。25-28行,當(dāng)窗口關(guān)閉時(shí),進(jìn)行的收尾工作。第31行enable托管主窗口。第23行判斷了當(dāng)前對(duì)話框是否是激活窗口,如果是的話,當(dāng)它關(guān)閉時(shí),它的托管主窗口應(yīng)該被激活(34-35L)。
1:??? hDlg = CreateMainWindow (&CreateInfo);
2:??? if (hDlg == HWND_INVALID)
3:??????? return -1;
4:
5:??? SetWindowAdditionalData2 (hDlg, (DWORD)(&retCode));
6:
7:??? if (hOwner)
8:??????? EnableWindow (hOwner, FALSE);
9:??
10:??? hFocus = GetNextDlgTabItem (hDlg, (HWND)0, FALSE);
11:??? if (SendMessage (hDlg, MSG_INITDIALOG, hFocus, lParam)) {
12:??????? if (hFocus)
13:??????????? SetFocus (hFocus);
14:??? }
15:??
16:??? ShowWindow (hDlg, SW_SHOWNORMAL);
17:??
18:??? while( GetMessage (&Msg, hDlg) ) {
19:??????? TranslateMessage (&Msg);
20:??????? DispatchMessage (&Msg);
21:??? }
22:
23:??? isActive = (GetActiveWindow() == hDlg);
24:
25:??? dlgDestroyAllControls (hDlg);
26:??? DestroyMainWindow (hDlg);
27:??? ThrowAwayMessages (hDlg);
28:??? MainWindowThreadCleanup (hDlg);
29:??
30:??? if (hOwner) {
31:??????? EnableWindow (hOwner, TRUE);
32:??????? if(isActive)
33:??????? {
34:??????????? ShowWindow (hOwner, SW_SHOWNORMAL);
35:??????????? SetActiveWindow (hOwner);
36:??????? }
37:??? }
38:
39:??? return retCode;
?
?
最后說(shuō)一下子窗口(即控件)的創(chuàng)建過(guò)程。在MiniGUI中通過(guò)調(diào)用CreateWindow函數(shù)(CreateWindow其實(shí)是CreateWindowEx函數(shù)的宏)可以建立某個(gè)控件。控件的創(chuàng)建需要一個(gè)PCONTROL結(jié)構(gòu)變量,下面這段代碼中的第1行獲取控件的主窗口。第4行通過(guò)向HWND_DESKTOP發(fā)送MSG_GETCTRLCLASSINFO,接受到消息之后會(huì)調(diào)用GetControlClassInfo函數(shù)根據(jù)傳入的spClassName來(lái)獲取控件的class info。控件的class info包括控件名稱,默認(rèn)的風(fēng)格和擴(kuò)展風(fēng)格,消息回調(diào)函數(shù)等。后續(xù)的代碼設(shè)置控件的屬性。
1:?? if (!(pMainWin = GetMainWindowPtrOfControl (hParentWnd)))
2:??????????? return HWND_INVALID;
3:
4:?? cci = (PCTRLCLASSINFO)SendMessage (HWND_DESKTOP,
5:??????????? MSG_GETCTRLCLASSINFO, 0, (LPARAM)spClassName);
6:??? if (!cci) return HWND_INVALID;
7:
8:??? pNewCtrl = calloc (1, sizeof (CONTROL));
9:
10:??? if (!pNewCtrl) return HWND_INVALID;
11:
12:??? pNewCtrl->DataType = TYPE_HWND;
13:??? pNewCtrl->WinType? = TYPE_CONTROL;
14:
15:??? pNewCtrl->left???? = x;
16:??? pNewCtrl->top????? = y;
17:??? pNewCtrl->right??? = x + w;
18:??? pNewCtrl->bottom?? = y + h;
??????? ……
?
設(shè)置完控件的屬性之后,向HWND_DESKTOP發(fā)送MSG_NEWCTRLINSTANCE消息,HWND_DESKTOP接受到之后,會(huì)調(diào)用dskOnNewCtrlInstance函數(shù)創(chuàng)建控件,將它添加到其父窗口的children鏈表中(1L)。第16-18行判斷是否可見(jiàn),可見(jiàn)的話,就更新窗口顯示它。
1: SendMessage (HWND_DESKTOP, MSG_NEWCTRLINSTANCE,
2:??????????????? (WPARAM)hParentWnd, (LPARAM)pNewCtrl);
3:
4: if (SendMessage ((HWND)pNewCtrl, MSG_CREATE,
5:?????????????????? (WPARAM)hParentWnd, (LPARAM)dwAddData)) {
6:?????? SendMessage (HWND_DESKTOP,
7:????????????????????? MSG_REMOVECTRLINSTANCE,
8:????????????????????? (WPARAM)hParentWnd, (LPARAM)pNewCtrl);
9:?????? goto error;
10:}
11: SendMessage ((HWND)pNewCtrl, MSG_SIZECHANGING,
12:???????????????? (WPARAM)&rcExpect, (LPARAM)&pNewCtrl->left);
13: SendMessage ((HWND)pNewCtrl, MSG_CHANGESIZE,
14:???????????????? (WPARAM)(&pNewCtrl->left), 0);
15:
16: if (pNewCtrl->pParent->dwStyle & WS_VISIBLE && pNewCtrl->dwStyle &
17:???? WS_VISIBLE)
18:?????? UpdateWindow ((HWND)pNewCtrl, TRUE);
?
總結(jié)
以上是生活随笔為你收集整理的MiniGUI细节处理(转)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: AB1601运行后反复复位问题排查过程
- 下一篇: MINIGUI 开发指南---GDI