MiniGUI细节处理(转)
MiniGUI編程--列表框
分類: minigui2009-11-04 20:40
列表框
LBS(ListBoxStyle)
以CTRL_LIST/"list"為類名調用CreateWindow
多選風格:LBS_MULTIPLESEL
高級風各:LBS_USEICON
LBS_CHECKBOX
LBS_AUTOCHECK
加上邊框WS_BORDER
加垂直滾動條WS_VSCROLL
加水平滾動條WS_HSCROLL
允許通知消息:LBS_NOTIFY
排序LBS_SORT
常用風格組合:
LBS_NOTIFY|LBS_SORT|WS_VSCROLL|WS_BORDER
加入字符串LB_ADDSTRING
最上面索引值為0
SendMessage傳遞字符串時節lParam指向字符串
添加以未尾
SendMessage(hwndlist,LB_ADDSTRING,0,(LPARAM)string);
插入字符串LB_INSERTSTRING
SendMessage(hwndlist,LB_INSERTSTRING,index,(LPARAM)string);
如指定期LBS_CHECKBOX/LBS_USEICON風格添加時不能傳字符串指針,而要使用LISTBOXITEMINFO結構
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);
刪除指定條目
發送LB_DELETESTRING消息
SendMessage(hwndlist,LB_DELETESTRING,index,0);
清空
SendMessage(hwndlist,LB_DELETESTRING,0,0);
獲取條目個數
發送LB_GETCOUNT消息
count=SendMessage(hwndlist,LB_GETCOUNT,0,0);
獲取指定條目字符串長度
發送LB_GETTEXTLEN
length=SendMessage(hwndlist,LB_GETTEXTLEN,index,0);
獲取條目
length=SendMessage(hwndlist,LB_GETTEXTLEN,index,(LPARAM)buffer);
設置條目
LB_SETTEXT
SendMessage(hwndlist,LB_SETTEXT,index,buffer);
高級列形框要使用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);
獲取當前選擇項
LB_GETCURSEL
index=SendMessage(hwndlist,LB_GETCURSEL,0,0);
設置當前選擇項
SendMessage(hwndlist,LB_SETCURSEL,index,0);
多選:
LB_GETSELCOUNT獲得被選中的條目個數
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);
獲取檢查框狀態
status=SendMessage(hwndlist,LB_GETCHECKMARK,index,0);
返回值:
CMFLAG_CHECKED選擇狀態
CMFLAG_PARTCHECKED部分選擇狀態
CMFLAG_BLANK未選擇狀態
設檢查框狀態
ret=SendMessage(hwndlist,LB_SETCHECKMARK,index,(LPARAM)status);
返回值:
LB_ERR失敗
LB_OKAY成功
為每個條目附加一個32位數據,在需要時取出該值
LB_SETITEMADDDATA
LB_GETITEMADDDATA
設置條目所占高度
LB_SETITEMHEIGHT
返回條目所占高度
LB_GETITEMHEIGHT
通知碼:
必須指定LBS_NOTIFY風格
LBN_ERRSPACE內存分配失敗
LBN_SELCHANGE當前選擇項發生變化
LBN_CLICKED單擊
LBN_DBLCLK雙擊
LBN_SELCANCEL取消選擇
LBN_SETFOCUS列表框獲得焦點
LBN_KILLFOCUS列表框失去焦點
LBN_CLICKCHECKMARK單擊條目檢查框
LBN_ENTER在列表框中按下Enter鍵
只有指下LBS_NOTIFY時,列表框才會向父窗口發送通知消息
如果用SetNotificationCallback設定了通知回調函數
則控件不發送MSG_COMMAND通知消息,而會直接調用設定的通知回調函數
MiniGUI編程--編輯框
2009-11-04 20:41
編輯框
ES(EditStyle)
單行CTRL_SLEDIT/"sledit"? SingleLineEdit
多行CTRL_MLEDIT/"textedit"? MultiLineEdit
通用風格
WS_CHILD|WS_VISIBLE|WS_BORDER
特有風格:
ES_UPPERCASE大寫
ES_LOWERCASE小寫
ES_PASSWORD密碼
ES_READONLY只讀
ES_BASELINE顯示虛線
ES_AUTOWRAP自動換行
ES_LEFT左對齊
ES_NOHIDESEL失去焦點保持文本的選中狀態
ES_AUTOSELECT得到焦點時自動先選中所有
ES_TITLE第一行顯示標題
ES_TIP提示信息
ES_CENTER文本居中對齊
ES_RIGHT文本右對齊
多行文本框指定滾動條:
WS_HSCROLL
WS_VSCROLL
消息:
MSG_GETTEXTLENGTH獲取文本長度
MSG_GETTEXT獲取文本
MSG_SETTEXT設置文本
或用以下函數
GetWindowTextLength
GetWindowText
SetWindowText
取得插入符位置
EM_GETCARETPOS
int line_pos;
int char_pos;
SendMessage(hwndedit,EM_GETCARETPOS,(WPARAM)&line_pos,(LPARAM)&char_pos);
參數:
line_pos行索引值
char_pos該行中的字符位置
設置插入符位置
EM_SETCARETPOS
int line_pos;
int char_pos;
SendMessage(hwndedit,EM_SETCARETPOS,line_pos,char_pos);
獲取當前選中文本
EM_GETSEL
char buffer[buf_len];
SendMessage(hwndedit,EM_GETSEL,buf_len,(LPARAM)buffer);
設置當前選中的文本
EM_SETSEL
int line_pos,char_pos;
SendMessage(hwndedit,EM_SETSEL,line_pos,char_pos);
lParam指定行索引值,wParam指定行內字符位置
獲取當前選擇點位置
EM_GETSELPOS
int line_pos,char_pos;
SendMessage(hwndedit,EM_GETSELPOS,(WPARAM)&line_pos,(LPARAM)&char_pos);
選擇所有字符相當于Ctrl+A
EM_SELECTALL
SendMessage(hwndedit,EM_SELECTALL,0,0);
復制到剪貼板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);
設置行高
EM_SETLINEHEIGHT
int line_height;
SendMessage(hwndedit,EM_SETLINEHEIGHT,line_height,0);
獲取行數
EM_GETLINECOUNT
int line_count;
line_count=SendMessage(hwndedit,EM_GETLINECOUNT,0,0);
設置文本上限
EM_LIMITTEXT
SendMessage(hwndedit,EM_LIMITTEXT,10,0L);
設置只讀
EM_SETREADONLY wParam為TRUE
取消只讀
EM_SETREADONLY wParam為FALSE
修改密碼顯示字符
EM_SETPASSWORDCHAR
SendMessage(hwndedit,EM_SETPASSWORDCHAR,'%',0L);
獲得當前密碼字符
EM_GETPASSWORDCHAR
設置提示文字
SLEDIT控件具有ES_TIP風格時
ES_SETTIPTEXT
獲取提示文字
ES_GETTIPTEXT
int len;
char *tip_text;
SendMessage(hwndedit,ES_SETTIPTEXT,len,(LPARAM)tip_text);
lParam指定字符串,wParam指定長度
或
int len;
char tip_text[len+1];
SendMessage(hwndedit,EM_GETTIPTEXT,len,(LPARAM)tip_text);
lParam指定緩沖區,wParam指定長度
當TEXTEDIT具有ES_TITLE風格時
EM_SETTITLETEXT設置標題文字
EM_GETTITLETEXT獲取標題文字
int len;
char *title_text;
SendMessage(hwndedit,EM_SETTITLETEXT,len,(LPARAM)title_text);
lParam指定字符串,wParam指定長度
或
int len;
char title_text[len+1];
SendMessage(hwnd,EM_GETTITLETEXT,len,(LPARAM)title_text)
lParam指定緩沖區,wParam指定長度
編輯框通知碼
編輯框沒有ES_NOTIFY風格
EN_SETFOCUS
EN_KILLFOCUS
EN_CHANGE
EN_ENTER
EN_MAXTEXT
EN_CLICKED
EN_DBLCLK
控件專用函數
GetNotificationCallback獲取控件的通知消息的回調函數
SetNotificationCallback設置控件的通知消息的回調函數
NotifyParentEx發送控件通知消息
MiniGUI編程--靜態框
分類: minigui2009-11-04 20:43
靜態框
以CTRL_STATIC/"static"為類名調用CreateWindow即可創建
風格
普通
SS_SIMPLE
SS_LEFT
SS_CENTER
SS_RIGHT
SS_LEFTNOWORDWRAP
位圖
SS_BITMAP
SS_ICON
dwAddData指定位圖/圖標對象指針
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
顏色風格
SS_WHITERECT
SS_GRAYRECT
SS_BLACKRECT
SS_WHITEFRAME
SS_BLACKFRAME
SS_GRAYFRAME
通知碼
必須設置SS_NOTIFY風格
單擊STN_CLICKED
雙擊STN_DBLCLK
按鈕
以CTRL_BUTTON/"button"為類我調用CreateWindow可創建按鈕
默認按鈕:BS_DEFPUSHBUTTON
按鈕向父窗口發送MSG_COMMAND和BN_CLICKED
多行風格:BS_MULTILINE
位圖風格:BS_BITMAP
圖標風格:BS_ICON
通過CreateWindow的dwAddData傳遞位圖/圖標對象的句柄
保持原有大小:BS_REALSIZEIMAGE
復選框
在按鈕基礎上指定以下兩種風格:
BS_CHECKBOX手動向控件發消息設置
BS_AUTOCHECKBOX自動設置小圓點
BS_3STATE
BS_AUTO3STATE
文字位置:
BS_LEFTTEXT
BS_LEFT
BS_CENTER
BS_RIGHT
BS_TOP
BS_VCENTER
BS_BOTTOM
單選按鈕
風格:
BS_RADIOBUTTON
BS_AUTORADIOBUTTON
文本位置:
BS_LEFTTEXT
BS_LEFT
BS_CENTER
BS_RIGHT
BS_TOP
BS_VCENTER
BS_BOTTOM
互斥在第一個單選鈕按設置WS_GROUP
按鈕消息
查詢/設置選中消息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
本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/creatory/archive/2007/12/03/1914461.aspx
MiniGUI編程--組合框
分類: minigui2009-11-04 20:39
組合框
以CTRL_COMBOBOX/"combobox"為類名調用CreateWindow
風格CBS->ComboBoxStyle
簡單組合框CBS_SIMPLE
下拉式組合框CBS_DROPDOWNLIST
在用CreateWindow創建組合框時用dwAddData參數指定列表框高度值
hcomb=CreateWindow(CTRL_COMBOBOX,"0",WS_VISIBLE|WS_TABSTOP|CBS_SIMPLE|CBS_SORT,IDC_BOX4,10,100,180,24,parent,100);
//指定dwAddData為100,即簡單組合框列表框的高度為100
旋轉組合框CBS_SPINLIST
箭頭在內容的左右風格:CBS_SPINARROW_LEFTRIGHT
箭頭在內容的上下風格:CBS_SPINARROW_TOPBOTTOM
其他風格:
CBS_READONLY
CBS_UPPERCASE
CBS_LOWERCASE
CBS_EDITBASELINE
CBS_SORT
CBS_EDITNOBORDER無邊框
CBS_AUTOFOCUS組合框獲得焦點,自動定位于編輯框中
旋鈕數字框
以CBS_AUTOSPIN風格創建
自動循環顯示風格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為上
旋鈕數字框消息
CB_GETSPINRNAGE 獲得可取的最大值和最小值
CB_SETSPINRANGE 設置可取的最大值和最小值
CB_SETSPINVALUE 設置編輯框當前值
CB_GETSPINVALUE 獲得編輯框當前值
組合框通知碼
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為類名調用CreateWindow
一般風格:WS_CHILD|WS_VISIBLE|MBS_SORT
MBS->MenuButtonStyle
MBS_SORT
MBS_LEFTARROW
MBS_NOBUTTON
MBS_ALIGNLEFT
MBS_ALIGNRIGHT
MBS_ALIGNCENTER
向菜單按鈕添加條目
使用MBM_ADDITEM消息和MENUBUTTONITEM結構
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);
設置當前選中條目
MBM_SETCURITEM
SendMessage(hMbtnwnd,MBM_SETCURITEM,index,0);
獲得當前選中條目
MBM_GETCURITEM
index=SendMessage(hMbtnwnd,MBM_GETCURITEM,0,0);
獲取條目數據
MBM_GETITEMDATA wParam指定索引值,lParam指向一個MENUBUTTONITEM結構的指針對性
設置條目數據
MBM_SETITEMDATA
which指定要獲取的數據項
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
進度條
以CTRL_PROGRESSBAR為類名調用CreateWindow創建
風格:PBS->ProgressBarStyle
PBS_NOTIFY使進度條產生通知消息
PBS_VERTICAL豎直顯示進度條
通用風格:
WS_CHILD|WS_VISIBLE|PBS_NOTIFY
進度條設置
PBM->ProgressBarModify
設置范圍
PBM_SETRANGE
SendMessage(hwndpb,PBM_SETRANGE,min,max);
設置步長
PBM_SETSTEP
SendMessage(hwndpb,PBM_SETSTEP,5,0);
設置當前進度
PBM_SETPOS
SendMessage(hwndpb,PBM_SETPOS,50,0);
在當前進度基礎上偏移
PBM_DELTAPOS
SendMessage(hwndpb,PBM_DELTAPOS,10,0);
前進一個步進值
PBM_STEPIT
SendMessage(hwndpb,PBM_STEPIT,0,0);
進度條通知碼
指定PBS_NOTIFY風格
PBN_REACHMAX
PBN_REACHMIN
滑塊
以CTRL_TRACKBAR為類名調用CreateWindow
通用風格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風格
TBN_CHANGE
TBN_REACHMAX
TBN_REACHMIN
工具欄
CTRL_TOOLBAR
CTRL_NEWTOOLBAR
CTRL_COOLBAR
以CTRL_NEWTOOLBAR為類名調用CreateWindow創建
創建工具欄
填充NTBINFO結構賦給CreateWindow的dwAddData能數
NTBINFO->NewToolBarINFO
成員
image
nr_cells
nr_cols
w_cell
h_cell
風格
NTBS_HORIZONTAL
NTBS_VERTICAL
NTBS_MULTLINE
NTBS_WITHTEXT
NTBS_TEXTRIGHT
NTBS_DRAWSTATES
NTBS_DRAWSEPARATOR
添加工具項
發送NTBM_ADDITEM消息傳遞NTBITEMINFO結構
成員
which :NTBM_GETTITEM/NTBM_SETITEM
flags :NTBIF_PUSHBUTTON/NTBIF_CHECKBUTTON/NTBIF_HOTSPOTBUTTON/NTBIF_NEWLINE
id??? :按鈕標識符
text? :指定NTBS_WITHTEXT風格時顯示的文本
tip?? :保留
bmp_cell
hotspot_proc
rc_hotspot
add_data
MiniGUI消息投遞方式
分類: minigui2009-11-04 20:38
消息發送方式:
1.將消息投遞到一個先進先出隊列中
2.直接把消息發給窗口過程
投遞到隊列中的消息主要有:
鍵盤和鼠標消息MSG_LBUTTONDOWN,MSG_MOUSEMOVE,MSG_KEYDOWN,MSG_CHAR
定時器消息MSG_TIMER
繪制消息MSG_PAINT
退出消息MSG_QUIT
可以用HavePendingMessage函數檢查消息隊列中是否有消息而不取出的消息
BOOL GUIAPI HavePendingMessage(HWND hMainWnd);
直接發送到窗口過程的消息一般用于通知窗口完成一些需要立即處理的事件,如MSG_ERASEBKGND消息
消息的處理
一般通過一個消息循環來處理消息隊列中的消息
GetMessage從消息隊列中取出消息
TranslateMessage翻譯消息
DispatchMessage發送消息
如下:
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中當要求等待消息立即返回以處理其他事務時可以使用HavePendingMessage
do
{
ReadMasterPty(pConInfo);
if(pConInfo->terminate)
break;
while(HavePendingMessage(hMainWnd))
{
if(!GetMessage(&msg,hMainWnd))
break;
DispatchMessage(&msg);
}
}while(true);
窗口過程是一個特定類型的函數,用于接收和處理所有發送到該窗口的消息
每個控件類也有一個窗口過程,屬于同一控件類的所有控件共用同一個窗口過程處理消息
如果窗口過程不處理某些消息一般把該消息傳給系統進行默認處理
int DefaultMainWinProc(HWND hwnd,int message,WPARAM wParam,LPARAM lParam);
對話框缺省消息處理函數
int DefaultDialogProc(HWND hwnd,int message,WPARAM wParam,LPARAM lParam);
控件窗口缺省消息處理函數
int DefaultControlProc(HWND hwnd,int message,WPARAM wParam,LPARAM lParam);
投遞:把一條消息復制到消息隊列中
發送: 直接把消息發送到窗口過程函數
消息處理函數:
PostMessage:將消息放到消息隊列后立即返回,用于發送非關鍵性消息,受消息緩沖區限制
SendMessage:將消息發送到窗口過程,等待處理完后返回
SendNotifyMessage:同PostMessage,采用鏈表處理,不受緩沖區限制,一般用于從控件向父窗口發送“通知消息”
PostQuitMessage:將MSG_QUIT消息投遞到消息隊列中
將指定消息廣播給桌面的所有主窗口:
int GUIAPI BroadcastMessage(int iMsg,WPARAM wParam,LPARAM lParam);
丟棄消息隊列中所有消息并返回個數
int GUIAPI ThrowAwayMessages(HWND pMainWnd);
等待一有消息就返回
BOOL GUIAPI WaitMessage(PMSG pMsg,HWND hMainWnd);
MiniGUI消息大全:
1.MSG_DESTROY
調用DestroyMainWindow/DestroyWindow時發送到窗口過程中
例:程序在MSG_DESTROY消息中銷毀被托管主窗口的位圖字體等資料
case MSG_DESTROY:
???? DestroyIocn(icon1);
???? DestroyIocn(icon2);
???? DestroyAllControls(hWnd);
???? return 0;
例:被托管主窗口響應MSG_CLOSE消息
case MSG_CLOSE:
???? DestroyMainWindow(hWnd);
???? MainWindowCleanup(hWnd);
???? return 0;
2.MSG_CLOSE
點擊“X”按鈕時向窗口過程發送該消息,程序該在響應該消息時調用DestroyMainWindow銷毀主窗口并用PostQuitMessage向隊列中投放MSG_QUIT消息
3.MSG_PAINT
窗口進行重繪時該消息被發送到窗口過程
窗口在初始顯示時
從隱藏狀態變為顯示狀態
從部分不可見到可見狀態
調用InvalidateRect時
窗口過程在收到該消息時應該對窗口進行界面維護
case MSG_PAINT:
?HDC hdc;
?hdc=BeginPaint(hwnd);
?...
?EndPaint(hwnd,hdc);
?return 0;
程序處理完后要直接返回,不應該再傳遞給默認窗口過程處理
4.MSG_ERASEBKGND
需要清除窗口背景時發送該消息
InvalidateRect/UpdateWindow并為bErase傳遞TRUE時
如果在MSG_PAINT消息時重繪所有的窗口客戶區應忽略該消息
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
調用SetWindowFont改變了默認字體后將引發該消息
窗口過程需要處理以便反映出新的字體設置
如編輯框就要處理并重繪自己:
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
當調用SetWindowFont改變默認字體時引發該消息
通常窗口過程將此消息傳遞給默認窗口過程處理
如果窗口不允許用戶改變字體可以加以截獲該消息將返回非零值
case MSG_FONTCHANGING:
???? return -1;
7.MSG_CREATE
窗口成功創建并添加到窗口管理器中時引發該消息
8.MSG_SIZECHANGED
窗口尺寸變化時發生,wParam包含窗口大小,lParam用于保存窗口客戶區大小的RECT指針
case MSG_SIZECHANGED:
RECT *rcClient=(RECT*)lParam;
rcClient->right=rcClient->left+_WIDTH;
rcClient->bottom=rcClient->top+_HEIGHT;
return 0;
9.MSG_SIZECHANGING
窗口尺寸發生變化時引發該消息,用于確定窗口大小
wParam包含預期窗口尺寸值,lParam用于保存結果值
case MSG_SIZECHANGING:
?memcpy((PRECT)lParam,(PRECT)wParam,sizeof(RECT));
?return 0;
可以截獲該消息使創建的窗口位于指定的位置或具有固定的大小
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
建立主窗口過程中引發, 此時窗口對象尚未建立,不能使用GetDC等函數
必須在此消息的處理中進行輸入法窗口注冊
case MSG_NCCREATE:
if(hz_input_init())
SendMessage(HWND_DESKTOP,MSG_IME_REGISTER,(WPARAM)hwnd,0);
else
return -1;
break;
MiniGUI通用窗口操作函數,可用于主窗口和控件
UpdateWindow? 立即更新某個窗口
ShowWindow??? 顯示/隱藏某個窗口
IsWindowVisible 判斷某個窗口是否可見
EnableWindow 激活/禁止某個窗口
IsWindowEnabled 判斷某個窗口是否可用
GetClientRect 取得客戶區矩形
GetWindowRect 取得窗口矩形
GetWindowBkColor 取得窗口背景色
SetWindowBkColor 設置窗口背景色
GetWindowFont 取得窗口默認字體
SetWindowFont 設置窗口默認字體
GetWindowCursor 取得窗口光標
SetWindowCursor 設置窗口光標
GetWindowStyle 取得窗口風格
GetWindowExStyle 取得窗口擴展風格
GetFocusChild 取得有輸入焦點的子窗口
SetFocusChild 設置焦點子窗口
GetWindowCallbackProc 取得窗口過程函數
SetWindowCallbackProc 設置窗口過程函數
GetWindowAdditionalData 取得窗口附加數據一
SetWindooAdditionalData 設置窗口附加數據一
GetWindowAdditionalData2
SetWindowAdditionalData2
GetWindowCaption 獲取窗口標題
SetWindowCaption 設置窗口標題
InvalidateRect 使窗口給定矩形區域無效,將引發窗口重繪
GetUpdateRect 獲取窗口當前無效區域外包矩形
ClientToScreen 客戶區坐標轉換為屏幕坐標
ScreenToClient 屏幕坐標轉換為客戶區坐標
WindowToScreen窗口坐標轉換為屏幕坐標
ScreenToWindow
IsMainWindow判斷給定窗口是否為主窗口
IsControl判斷給定窗口控件
IsDialog斷送給定窗口是否為對話框
GetParent獲取父窗口句柄,主窗口父窗口為HWND_DESKTOP
GetMainWindowHandle獲取某個窗口的主窗口句柄
GetNextChild取得下一個子窗口
GetNextMainWindow取得下一個主窗口句柄
GetHosting獲取某個窗口的托管窗口
GetFirstHosted 取得某個主窗口的第一個被托管窗口
GetNextHosted 獲取下一人被托管窗口
GetActiveWindow 取得當前活動窗口
SetActiveWindow 設置當前活動窗口
GetCapture獲取當前捕獲鼠標的窗口
SetCapture捕獲
ReleaseCapture釋放
MoveWindow移動/改變窗口大小
ScrollWindow滾動窗口客戶區內容
創建簡單的控件
調用CreateWindow直接創建子窗口
或使用對話框模板創建一類控件
模板結構<minigui/window.h>中定義
用于定義控件
typedef struct
{
char *class_name; //控件類
DWORD dwStyle; //風格
int x,y,w,h; //控件在對話框中的位置
int id; //控件ID
const char *caption; //控件標題
DWORD dwAddData; //附加數據
DWORD dwExStyle; //擴展風格
}CTRLDATA;
typedef CTRLDATA *PCTRLDATA;
用于定義對話框模板
typedef struct
{
DWORD dwStyle; //對話框風格
DWORD dwExStyle; //對話框擴展風格
int x,y,w,h; //對話框位置
const char*caption; //對話框標題
HICON hIcon; //對話框圖標
HMENU hMenu; //對話框菜單
int controllnr; //控件數目
PCTRLDATA controls; //指同控件數組的指針
DWORD dwAddData;? //附加數據,必須為0
}DLGTEMPLATE;
typedef DLGTEMPLATE *PDLGTEMPLATE;
結構CTRLDATA用于定義控件,DLGTEMPLATE用于定義對話框本身
程序應首先用CTRLDATA定義對話框中所有的控件并用數組表示
控件在數組中的順序就是用戶按TAB時的切換順序
然后定義對話框
指定對話框中的控件數目
并指定DLGTEMPLATE->controls指向控件數組
例:
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
}
};
應盡量將定義的對話框模板數據接口定義為static類型,使其僅在該文件中有效,以免造成錯誤
MiniGUI對話框編程
分類: minigui2009-11-04 20:38
定義對話框模板后,再定義對話框回調函數并調用DialogBoxIndirectParam建立對話框
例:
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);
}
創建對話框函數
int GUIAPI DialogBoxIndirectParam(PDLGTEMPLATE pDlgTemplate,HWND hOwner,WNDPROC DlgProc,LPARAM lParam);
參數:對話框模板,托管主窗口句柄,回調函數地址,附加參數值
BOOL GUIAPI EndDialog(HWND hDlg,int endcode);
結束對話框過程
void GUIAPI DestroyAllControls(HWND hDlg);
銷毀對話框中所有子控件
創建非模態對話框
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);
}
}
對話框控件風格
WS_GROUP? 成為同組控件頭一個
WS_TABSTOP 支持TAB切換
對話框操作函數:
DestroyAllControls
GetDlgCtrlID
GetDlgItem
GetDlgItemInt
SetDlgItemInt
GetDlgItemText
GetDlgItemText2
SetDlgItemText
GetNextDlgGroupItem
GetNextDlgGroupItem
SendDlgItemMessage
CheckDlgButton
CheckRadioButton
IsDlgButtonChecked
GetDlgDefPushButton
MinGUI預定義控件類:
"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
調用CreateWindow/CreateWindowEx創建預定義控件類的實例
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)?
參數:
控件類,標題,風格,標識符,位置,父窗口,附加數據
例:
#define IDC_STATIC1 100
#define IDC_STATIC2 150
#define BUTTON1 110
#define BUTTON2 120
#define EDIT1 130
#define EDIT2 140
//創建一個靜態框
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中創建兩個按鈕
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中創建一個編輯框
hEdit1=CreateWindow(CTRL_EDIT,"edit box 1",
WS_CHILD|WS_VISIBLE|WS_BORDER,
IDC_EDIT1,
20,80,100,24,
hStaticWnd1,
0);
//在hStaticWnd1中創建一個靜態框
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中創建一個編輯框(為hStaticWnd1的孫窗口)
hEdit2=CreateWindow(CTRL_EDIT,"edit box 2",
WS_CHILD|WS_VISIBLE|WS_BORDER,
IDC_EDIT2,
0,20,100,24,
hStaticWnd2,
0);
控件內部發生事件時,向父窗口發送MSG_COMMAND消息
該消息的wParam由子窗口標識符和通知碼組成
lParam含有發出通知消息的控件句柄
如:
編輯框向父窗口發送EN_CHANGE消息
switch(message)
{
case MSG_COMMAND:
int id=LOWORD(wParam);
int nc=HIWORD(wParam);
if(id==ID_MYEDIT&&nc==EN_CHANGE)
{...
}
break;
}
設置控件通知消息回調函數
SetNotificationCallback
例:
編輯框的回調函數
static void notif_proc(HWND hwnd,int id,int nc,DWORD add_data)
當對話框中有多個控件時要分別定義每一個控件的回調函數
并在對話框初始話消息時設置
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;
學習MiniGUI之窗口創建篇
分類: minigui2009-11-04 12:56
最近在學習MiniGui,將一些分析的結果貼出來供大家參考,同時歡迎大家的指正。
圖形編程中,窗口是一個重要的概念,窗口其實是一個矩形框,應用程序可以使用其從而達到輸出結果和接受用戶輸入的效果。窗口系統(Window System)界于操作系統層次之上,它是一個軟件系統,負責把顯示屏幕分隔為不同的部分來幫助用戶管理和控制不同的顯示環境,它提供基于窗口的工作模式。在Linux上面,X就是一個典型的窗口系統吧。
?? 在MiniGui中有三種窗口類型:主窗口,對話框和控件窗口。主窗口作為應用程序的主界面或開始界面。子窗口通常是控件窗口,也可以是自定義窗口類,這里的控件窗口說白了就是一些窗口上面的控件,比如按鈕,編輯框等。對話框其實就是主窗口,只不過一般為了完成特殊用途,所以在此加以區分。
?? 下面我們一起來看看這三種窗口類型的創建吧。首先看CreateMainWindow函數,它創建一個主窗口:由于代碼比較長,這里就不全部貼出了,主要是說說關鍵的部分。
?? CreateMainWindow函數通過接受PMAINWINCREATE類型的參數而創建一個窗口,并返回其句柄。關于PMAINWINCREATE結構的具體成員變量,大家可以去查看源碼。下面主要對函數內部做個簡單介紹。
1.?????? 聲明一個PMAINWIN類型,并分配空間,該變量用來存放創建的主窗口的信息
2.?????? 說下面的代碼之前,先說說托管(Hosting)窗口和被托管(Hosted)窗口吧。我們知道MiniGui內部實現了消息機制,即當有鍵盤輸入事件發生時,就往消息隊列中發送鍵盤消息,而一般是主窗口會不停的從消息隊列中取出消息來處理,或者自己響應,或者忽略,或者派發給其他的窗口。那么這里就有一個問題,消息隊列是每個主窗口都有一個呢,還是所有的主窗口都使用同一個消息隊列?在MiniGui中有個特殊的主窗口HWND_DESKTOP,它是所有窗口的父窗口,直觀的說就是整個桌面的窗口。當一個主窗口在創建的時候,可以指定新建一個消息隊列,也可以使用別的主窗口的消息隊列,如果是后者,假設主窗口A在創建時指定使用主窗口B的消息隊列,那么A就被稱為被托管窗口,而B則被稱為托管窗口。所以很明顯CreateInfo.hHosting就是用來指明托管窗口的。來看下面的代碼,這里對MiniGUI的兩種運行模式進行了區分,1-15行是MiniGUI-Threads模式,在這種模式下,如果托管窗口為HWND_DESKTOP,則新建一個消息隊列(2-12行);如果托管窗口不為HWND_DESKTOP,則返回hHosting所在的主窗口的消息隊列。16行是非MiniGUI-Threads模式下,僅僅表明新的主窗口使用HWND_DESKTOP的消息隊列,這里其實忽略了pHosting參數。
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.?????? 下面的幾行是對pWin進行初始化的操作,第1行賦值消息處理回調函數。第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.?????? 初始化結束之后,就開始發送消息通知自身來真正的繪制窗口了。1-4行發送本窗口的MSG_SIZECHANGING和MSG_CHANGESIZE消息,會調用本窗口消息回調函數中的相應處理部分。第6行是發送MSG_ADDNEWMAINWIN消息給HWND_DESKTOP窗口,HWND_DESKTOP窗口主要負責初始化Clip區和Invalid區,并且把當前窗口添加到sg_MainWinZOrder鏈表里,這個鏈表記錄的是所有窗口的疊加順序,在顯示和隱藏窗口的時候,疊加順序很重要,它會決定屏幕上哪些窗口會受影響而需要重繪。第9行發送MSG_CREATE消息給窗口,窗口接受到此消息一般進行子窗口的初始化和創建,如果創建失敗了,則通知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: }
?
?
接下來我們看對話框的創建過程,對話框分為模態和非模態對話框。非模態對話框的創建過程和主窗口的創建過程差不多,其中也調用了CreateMainWindow函數,之后還調用了CreateWindowEx創建對話框上的控件。模態對話框就是顯示之后,用戶不能再切換到其他主窗口進行工作的對話框,而只能在關閉之后,才能使用其他的主窗口,通過DialogBoxIndirectParam創建,一開始的步驟與非模態對話框類似,以下的代碼是其不同的部分:第7行,hOwner是待創建對話框的托管主窗口,這里其實是把它disable掉了。第11行是處理MSG_INITDIALOG消息。第18-21行,是消息處理的循環機制,這里可以看到這就是為什么模態對話框一定要等到關閉之后,才可以使用其它的主窗口,這里還需要注意一點,由于是從對話框的托管主窗口是HWND_DESKTOP窗口,因此他們共用一個消息隊列,此時,對話框可能接受到發送給托管主窗口的消息,而由于在第7行中已經將托管主窗口的dwStyle設置為WS_DISABLE了,因此在這些消息處理流程里面可以做相應的處理(例如當窗口被設置為WS_DISABLE時,忽略該消息)。25-28行,當窗口關閉時,進行的收尾工作。第31行enable托管主窗口。第23行判斷了當前對話框是否是激活窗口,如果是的話,當它關閉時,它的托管主窗口應該被激活(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;
?
?
最后說一下子窗口(即控件)的創建過程。在MiniGUI中通過調用CreateWindow函數(CreateWindow其實是CreateWindowEx函數的宏)可以建立某個控件??丶膭摻ㄐ枰粋€PCONTROL結構變量,下面這段代碼中的第1行獲取控件的主窗口。第4行通過向HWND_DESKTOP發送MSG_GETCTRLCLASSINFO,接受到消息之后會調用GetControlClassInfo函數根據傳入的spClassName來獲取控件的class info??丶腸lass info包括控件名稱,默認的風格和擴展風格,消息回調函數等。后續的代碼設置控件的屬性。
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;
??????? ……
?
設置完控件的屬性之后,向HWND_DESKTOP發送MSG_NEWCTRLINSTANCE消息,HWND_DESKTOP接受到之后,會調用dskOnNewCtrlInstance函數創建控件,將它添加到其父窗口的children鏈表中(1L)。第16-18行判斷是否可見,可見的話,就更新窗口顯示它。
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);
?
總結
以上是生活随笔為你收集整理的MiniGUI细节处理(转)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: AB1601运行后反复复位问题排查过程
- 下一篇: MINIGUI 开发指南---GDI