第 3 章 以對話盒為界面的程式


以對話盒為界面的程式

這一章,小木偶打算介紹在 WIN64 系統下,以組合語言撰寫對話盒界面的程式。以對話盒為界面的程式,建立視窗很方便,而且能處理許多人機界面的問題,此外不須撰寫訊息迴圈、建立視窗類別等程式碼,既方便又簡潔,小木偶很喜歡這類程式。底下介紹撰寫這種程式的過程。

對話盒面板 ( Dialog Template )

與 WIN32 系統一樣,要先建立資源描述檔 ( 副檔名為 *.RC ),資源描述檔是一種純文字檔,應以 ASCII 編碼方式儲存。然後在資源描述檔堶情A加上一個稱為對話盒面板 ( dialog template ) 的段落。對話盒面板堶控埻z了對話盒風格、字形等屬性,還有各種控制項。底下就是常見的對話面板的模樣:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
name    DIALOG  x, y, width, height
CAPTION         caption_text
CHARACTERISTICS dword
CLASS           class_name
EXSTYLE         extended-styles
FONT            pointsize, typeface
LANGUAGE        language, sublanguage
MENU            menuname
STYLE           sytle
VERSION         dword
BEGIN
 CONTROL   "text", ID, class_name, style, x, y, width, height, exStyle
 ……
END

上面的對話盒面板,從第 2∼10 行,都是可有可無的選項,如果沒設定,就會依據內定值。第 11 和第 14 行,是一對 BEGIN/END,也可以用一對 {、} 代替,在 BEGIN/END 或 {、} 內包含了各種控制項,每一條 CONTROL 代表一個控制項。底下先說明可有可無的選項。

  1. 第一行的 DIALOG 是資源描述檔的關鍵字,表示從這兒開始的區塊,是描述對話盒面板的區塊了。name 是對話盒名稱,可以是字串或是正整數 ( 此正整數稱為對話盒識別碼 )。不管是字串或正整數,都必須與原始碼內,呼叫建立對話盒的 DialogBoxParam API 時,所用的第二個參數所指字串或識別碼相同。這樣系統才能正確地知道要如何建立對話盒,也才能知道對話盒內有那些控制項。x、y 是建立的對話盒左上角在螢幕的位置,width、height 則是對話盒的寬與高,x、y、width、height 的單位不是螢幕上的點 ( 一般一個點稱為一個圖素 ),而是邏輯單位。
  2. 「CAPTION caption_text」是用來表示對話盒標題欄的字串,caption_text 也要用兩個「"」括起來。例如:
    CAPTION "最大公因數與最小公倍數"
  3. 第三行的 CHARACTERISTICS 是程式設計師自行定義的雙字組,供資源編譯器,亦即 RC.EXE,使用,作業系統不用這個數值。
  4. 「CLASS class_name」是設定對話盒的類別,class_name 可以是正整數識別碼或是字串,如果是字串要用兩個「"」括起來。如果沒有指定 CLASS,那麼作業系統會使用對話盒標準類別。
  5. 「EXSTYLE extended-styles」是設定對話盒的延伸風格,可以使用的延伸風格與 CreateWindowEx 的第一個參數相同,常見的延伸風格請到註三查閱。
  6. FONT 是用來指定對話盒的字形,pointsize 是字形大小;typeface 是字形名稱,可用兩個「"」括起來。例如下面的例子:
    FONT    8,"Times New Roman"
  7. 「LANGUAGE language, sublanguage」指定對所用的語言,「language」與「sublanguage」分別是指語言和地區,例如講英文的地區不只英國、美國,還有加拿大等國家。如果是美國的英語,「language」為「LANG_ENGLISH」,「sublanguage」為「SUBLANG_ENGLISH_US」;如果是加拿大的英語,「language」還是為「LANG_ENGLISH」,但「sublanguage」變為「SUBLANG_ENGLISH_CAN」。常用的語言請按註一查閱。
  8. MENU menuname 是指定所使用的選單,可以是正整數識別碼或是字串,但與原始碼的選單識別碼或選單名稱相同。
  9. STYLE 是用來表示對話盒的風格,這些風格其實是許多位元組合而成。它們也可以是視窗風格,例如 WS_POPUP、WS_SYSMENU等;也可以是對話盒風格,例如 DS_MODALFRAME。一般而言,彈出的對話盒,如果要有標題欄、系統選單,那麼就會包含 WS_POPUP、WS_SYSMENU 和 WS_CAPTION。如果模式對話盒要有邊框,那就要設定 DS_MODALFRAME;非模式對話盒則設定 WS_BORDER。如果非模式對話盒設定了 WS_VISIBLE,那麼建立好對話盒之後,就會立刻顯示,不然要呼叫 ShowWindow API;模式對話盒則是不管有沒有設定 WS_VISIBLE,都會立即顯示。常用的風格請到註二查閱。
  10. VERSION 敘述是用來描述對話盒版本,是使用者自行定義的雙字組,不儲存於可執行檔堙A系統用不著這個敘述。
  11. 第 11 到 14 行是一對 BEGIN/END 包含著許多控制項,BEGIN/END 也可以用一對大括號「{」、「}」代替。這些控制項將會顯示在對話盒堙A作為與使用者溝通的介面。

控制項

模式對話盒的觀念和在 Win32 系統一樣,它是一個包含著許多子視窗的視窗。這些子視窗 ( child window ) 也叫控制元件 ( 英文稱 control,或簡稱「控件」或「控制項」)。如同上面講過,這些控制項包含在對話盒面板的 BEGIN/END 敘述堙C定義控制項有兩種方法,第一種是

CONTROL  "text", ID, class_name, style, x, y, width, height, exStyle

"text" 是控制項的預定文字,ID 是識別號碼,x、y 是子視窗的位置,width、height 是子視窗的寬與高,style 是子視窗風格。class_name 是在系統中已預先定義的視窗類別,可以用 STATIC 表示靜態類別,BUTTON 表示按鈕類別,EDIT 表示編輯框類別,COMBOBOX 表示複合類別,LISTBOX 表示列表盒類別,SCROLLBAR 表示捲軸類別等六種。

不同類別的控制項可用的風格不盡相同,例如編輯框控制項與按鈕控制項看起來是截然不同的兩種的控制項,然則它們都是子視窗,產生方法相同但具有不同的風格,而是窗類別種類至少有這六種,所使用風格更多,所以要瞭解它們不事件易事。有時即使是同一類別的視窗,其外觀與使用方式亦相去甚遠,例如 BUTTON 類別中有檢驗盒、下壓式按鈕、圓形按鈕等數種控制項。像這樣具有相同的視窗類別,卻因風格不同而外觀與使用方式也不同,僅以風格來區別,並不是一目了然的做法。下面的例子中,第一個表示下壓式按鈕控制項,第二個是檢驗盒控制項:

CONTROL  "確定"    ,1,"BUTTON",BS_PUSHBUTTON,100, 20, 50, 14
CONTROL  "向右對齊",2,"BUTTON",BS_CHECKBOX  , 10, 10, 50, 14

但是如果不詳細檢查其後的風格,很不容易判斷,有時風格是又臭又長,那麼判讀更為困難。所以 RC.EXE 也允許第二種表示控件項的方式:

control-type  "text", ID, x, y, width, height [,styles]

這時 control-type 就能表示出各種控制項與部分風格了,例如下面右邊是以傳統方式表達下壓式按鈕與檢驗盒的方式,而右邊則是以較為簡潔的方式表達,事實上,兩者是相同的。

PUSHBUTTON  "確定"    ,1,100, 20, 50, 14
CHECKBOX    "向右對齊",2, 10, 10, 50, 14
CONTROL  "確定"    ,1,"BUTTON",BS_PUSHBUTTON,100, 20, 50, 14
CONTROL  "向右對齊",2,"BUTTON",BS_CHECKBOX  , 10, 10, 50, 14

以簡潔方式描述控制項的方式,可以按註四閱讀。

模式對話盒

底下更進一步說明 CLASS 在建立模式與非模式對話盒的角色:

底下以一個例子,求最大公因數,來說明「以對話盒為主」的程式撰寫過程。


求最小公因數

接下來寫一個範例,這個程式能讓使用者輸入兩個正整數,然後計算這兩個正整數的最大公因數與最小公倍數。執行畫面如下圖:

原理

在數學上,要計算兩正整數的最大公因數,可以用輾轉相除法。步驟是先挑選較大的數為被除數,較小的數為除數,相除之後的餘數為除數,原來的除數變為被除數,再相除。如此一直重複上述步驟,直到餘數為零時,該次除數為最大公因數,可以參考下面的流程圖。圖中,為配合組合語言除法,故以暫存器表示。在組合語言堙A除法中的被除數均放在 RDX:RAX 暫存器堙A除數可用任何一個 64 位元暫存器,或 64 位元的變數表示。而在每次相除之前,要把 RDX 設為 0,以免影響結果。

原始碼

底下是 GCD64.ASM 的內容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
        OPTION  CASEMAP:NONE
        OPTION  WIN64:3

UNICODE         EQU     1       ;使用萬國碼
IDC_NUM1        EQU     20000
IDC_NUM2        EQU     20001
IDC_GCD         EQU     20003
IDC_LCM         EQU     20004
IDC_CALC        EQU     20005
IDC_EXIT        EQU     20006

INCLUDE         WINDOWS.INC
INCLUDE         COMMCTRL.INC
INCLUDELIB      KERNEL32.LIB
INCLUDELIB      USER32.LIB
INCLUDELIB      COMCTL32.LIB

;*************************************************************************************************************
.CONST
szDlgName       DW      47h,43h,44h,0h                                                  ;對話盒面板名稱=GCD
szIcon          DW      47h,43h,44h,5fh,4ch,43h,4dh,0h                                  ;圖示名稱=GCD_LCM
szGCD           DW      6700h,5927h,516ch,56e0h,6578h,70bah,0ff1ah,25h,75h,0h           ;最大公因數為:%u
szLCM           DW      6700h,5c0fh,516ch,500dh,6578h,70bah,0ff1ah,25h,75h,0h           ;最小公倍數為:%u
;*************************************************************************************************************
.DATA
hInstance       DQ      ?       ;執行實例代碼
nNum1           DQ      ?
nNum2           DQ      ?
nGCD            DQ      ?       ;GCD
nLCM            DQ      ?       ;LCM
Translated      DQ      ?       ;呼叫GetDlgItemInt返回後,是否錯誤
szAnswer        DB      100 DUP (?)
;*************************************************************************************************************
.CODE
;-------------------------------------------------------------------------------------------------------------
;求RAX、R10兩暫存器內的最大公因數
find_gcd_lcm    PROC
                mov     rax,nNum1
                mov     r10,nNum2
;先求最大公因數,用輾轉相除法。先比較RAX、R10何者為大,大的當被除數,存於EAX堙F小的當除數,存於nGCD堙C
;兩者相除,如果餘數不為零,則原除數變為被除數,餘數變為除數,再重複相除,直到餘數為零時,最大公因數即為除數。
    .IF rax<r10
                mov     nGCD,rax
                mov     rax,r10
    .ELSE
<                mov     nGCD,r10/div>
    .ENDIF
next_loop:      sub     rdx,rdx
                div     nGCD
    .IF edx!=0
                mov     rax,nGCD
                mov     nGCD,rdx
                jmp     next_loop
    .ENDIF
                sub     rdx,rdx
                mov     r11,nGCD
                mov     rax,nNum1
                div     r11
                mul     nNum2
                mov     nLCM,rax
                ret
find_gcd_lcm    ENDP
;-------------------------------------------------------------------------------------------------------------
DlgProc         PROC    hDlg:QWORD,uMsg:DWORD,wParam:QWORD,lParam:QWORD
.IF rdx==WM_INITDIALOG
                INVOKE  LoadIcon,hInstance,OFFSET szIcon
                INVOKE  SendMessage,hDlg,WM_SETICON,ICON_SMALL,rax

.ELSEIF rdx==WM_COMMAND
                mov     r10,r8
                mov     r11,r8
                shr     r10,20h         ;R10D=通知碼
                and     r11,0ffffffffh  ;R11D=控制元件識別碼
   .IF r10d==BN_CLICKED
       .IF r11d==IDC_EXIT
                jmp     exit
       .ELSEIF r11d==IDC_CALC
                INVOKE  GetDlgItemInt,hDlg,IDC_NUM1,OFFSET Translated,0
                mov     nNum1,rax
                INVOKE  GetDlgItemInt,hDlg,IDC_NUM2,OFFSET Translated,0
                mov     nNum2,rax
                call    find_gcd_lcm
                INVOKE  wsprintf,OFFSET szAnswer,OFFSET szGCD,nGCD
                INVOKE  SetDlgItemText,hDlg,IDC_GCD,OFFSET szAnswer
                INVOKE  wsprintf,OFFSET szAnswer,OFFSET szLCM,nLCM
                INVOKE  SetDlgItemText,hDlg,IDC_LCM,OFFSET szAnswer
       .ENDIF
   .ENDIF

.ELSEIF rdx==WM_CLOSE
exit:           INVOKE  EndDialog,hDlg,0

.ELSE           ;其他未處理的訊息返回 FALSE
                mov     rax,0
                ret
.ENDIF          ;已處理的訊息,返回 TRUE

                mov     rax,1
                ret
DlgProc         ENDP
;-------------------------------------------------------------------------------------------------------------
main            PROC
                INVOKE  GetModuleHandle,0
                mov     hInstance,rax
                INVOKE  DialogBoxParam,hInstance,OFFSET szDlgName,0,OFFSET DlgProc,0
                INVOKE  ExitProcess,eax
                INVOKE  InitCommonControls
main            ENDP
;*************************************************************************************************************
END             main

底下是 GCD64.RC 的內容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include "c:\masm32\include\resource.h"

#define  RT_MANIFEST     24

#define IDC_NUM1        20000
#define IDC_NUM2        20001
#define IDC_GCD         20003
#define IDC_LCM         20004
#define IDC_CALC        20005
#define IDC_EXIT        20006

GCD  DIALOG  800,300,122,90
STYLE   DS_MODALFRAME|WS_POPUP|WS_VISIBLE|WS_CAPTION|WS_SYSMENU|DS_CENTERMOUSE|DS_CONTEXTHELP
FONT    8,"Times New Roman"
CAPTION "最大公因數與最小公倍數"
BEGIN
 CONTROL        "輸入第一個正整數:",         -1,"static",SS_LEFT|WS_CHILD|WS_VISIBLE|WS_GROUP, 6, 6, 75, 14
 CONTROL        "輸入第二個正整數:",         -1,"static",SS_LEFT|WS_CHILD|WS_VISIBLE|WS_GROUP, 6,20, 75, 14
 EDITTEXT       IDC_NUM1,80, 4, 38, 12, WS_TABSTOP|ES_NUMBER|ES_RIGHT|ES_AUTOHSCROLL
 EDITTEXT       IDC_NUM2,80,19, 38, 12, WS_TABSTOP|ES_NUMBER|ES_RIGHT|ES_AUTOHSCROLL
 CONTROL        "最大公因數為:",IDC_GCD,"static",SS_LEFT|WS_CHILD|WS_VISIBLE|WS_GROUP, 6,34,100, 14
 CONTROL        "最小公倍數為:",IDC_LCM,"static",SS_LEFT|WS_CHILD|WS_VISIBLE|WS_GROUP, 6,48,100, 14
 DEFPUSHBUTTON  "計算"          ,IDC_CALC,10,65, 50,18
 PUSHBUTTON     "離開"          ,IDC_EXIT,63,65, 50,18
END

1       RT_MANIFEST MOVEABLE PURE "GCD64.EXE.MANIFEST"

GCD_LCM ICON    GCD_LCM.ico

進入「命令提示字元」後,先執行前一章的 JWASM.BAT,這個程式是用來設定組譯環境,詳細情形參閱前一章。接下來,切換到原始程式所在的磁碟機與子目錄堙A然後才編譯資源描述檔、組譯組合語言原始程式、連結。請看下面的步驟:

C:\Users\wanker>jwasm [Enter]

C:\Users\wanker>SET INCLUDE=C:\JWASM\INCLUDE;

C:\Users\wanker>SET LIB=C:\JWASM\LIB;

C:\Users\wanker>SET PATH=C:\JWASM;C:\ProgramData\Oracle\Java\javapath;C:\Windows
\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerSh
ell\v1.0\

C:\Users\wanker>SET LINK=/SUBSYSTEM:WINDOWS /DEBUG

C:\Users\wanker>E: [Enter]   →切換到原始程式所在的磁碟機

E:\>cd E:\HomePage\SOURCE\WIN64\GCD_LCM [Enter]   →切換到原始程式所在的子目錄

E:\HomePage\SOURCE\Win64\GCD_LCM>rc gcd64.rc [Enter]
Microsoft (R) Windows (R) Resource Compiler Version 6.0.5724.0
Copyright (C) Microsoft Corporation.  All rights reserved.


E:\HomePage\SOURCE\Win64\GCD_LCM>jwasm -win64 gcd64.asm [Enter]
JWasm v2.12pre, Nov 27 2013, Masm-compatible assembler.
Portions Copyright (c) 1992-2002 Sybase, Inc. All Rights Reserved.
Source code is available under the Sybase Open Watcom Public License.

GCD64.ASM: 109 lines, 2 passes, 842 ms, 0 warnings, 0 errors

E:\HomePage\SOURCE\Win64\GCD_LCM>link gcd64.obj gcd64.res [Enter]
Microsoft (R) Incremental Linker Version 9.00.21022.08
Copyright (C) Microsoft Corporation.  All rights reserved.

/SUBSYSTEM:WINDOWS /DEBUG

E:\HomePage\SOURCE\Win64\GCD_LCM>

這一章只寫出如何用 Win64 組合語言製作模式對話盒為基礎的視窗程式,您得要有 Win32 的基礎才行,請參閱Win32 組合語言的對話盒與資源檔


註一:常見的語言

語文Language 及數值Sublanguage Sublanguage
之數值
說  明
中文LANG_CHINESE
04h
SUBLANG_CHINESE_TRADITIONAL01h中華民國使用正體中文
SUBLANG_CHINESE_SIMPLIFIED02h大陸上使用簡體中文
SUBLANG_CHINESE_HONGKONG03h香港使用的正體中文
SUBLANG_CHINESE_SINGAPORE04h新加坡使用的正體中文
SUBLANG_CHINESE_MACAU05h澳門使用的正體中文
英文LANG_ENGLISH
09h
SUBLANG_ENGLISH_US01h美國使用的英文
SUBLANG_ENGLISH_UK02h英國使用的英文
SUBLANG_ENGLISH_AUS03h澳洲使用的英文
SUBLANG_ENGLISH_CAN04h加拿大使用的英文
SUBLANG_ENGLISH_NZ05h紐西蘭使用的英文
SUBLANG_ENGLISH_IRELAND06h愛爾蘭使用的英文
SUBLANG_ENGLISH_SOUTH_AFRICA07h南非共和國使用的英文
SUBLANG_ENGLISH_JAMAICA08h牙買加使用的英文
SUBLANG_ENGLISH_CARIBBEAN09h加勒比使用的英文
SUBLANG_ENGLISH_BELIZE0ah貝里斯使用的英文
SUBLANG_ENGLISH_TRINIDAD0bh千里達及托巴哥使用的英文
SUBLANG_ENGLISH_ZIMBABWE0ch辛巴威使用的英文
SUBLANG_ENGLISH_PHILIPPINES0dh菲律賓使用的英文
SUBLANG_ENGLISH_INDIA10h印度使用的英文
SUBLANG_ENGLISH_MALAYSIA11h馬來西亞使用的英文
SUBLANG_ENGLISH_SINGAPORE12h新加坡使用的英文
北印度語LANG_HINDI
39h
SUBLANG_HINDI_INDIA01h印度使用的語言

language 與 sublanguage 合起來組成一個字組 ( 16 位元長 ) 稱為語言識別碼 ( language identifier )。這個字組的 0∼9 位元代表 language,第 10∼15 位元代表 sublanguage。例如查閱上表,可知中華民國台灣地區使用的正體中文之「sublanguage」為 01h,而「language」為 04h,依據「language」為 0∼9 位元、「sublanguage」為第 10∼15 位元合併後,語言識別碼就是 0404h,組成方式參見下圖:

註二:常見的風格

風格數值說  明
DS_3DLOOK4h不用粗體字,同時以三維方式畫出對話盒內的控制項四周的邊框。
DS_ABSALIGN1h對話盒的座標使用螢幕座標,而不是對話盒工作區的座標。
DS_CENTER800h把對話盒放置在桌面的中央,所謂的中央是不含底下的工作列。即使在「name DIALOG x, y, cx, cy」指定了 x、y,而又同時具有 DS_CENTER 風格,系統仍會把對話盒放在中央。
DS_CENTERMOUSE1000h在滑鼠游標位置上顯示對話盒。
DS_CONTEXTHELP2000h在標題欄右邊顯示「說明按鈕」。當使用者按下「說明按鈕」後,遊標會變成,然後使用者在某個控制項按下滑鼠左鍵後,系統會把 WM_HELP 傳給控制項的視窗函式。一般而言,控制項不處理,而傳給對話盒的視窗函式,然後在對話盒的視窗函式中以 HELP_WM_HELP 為參數,呼叫 WinHelp API,顯示說明內容。
DS_CONTROL400h具有此風格的對話盒的行為,像是另一個對話盒的子視窗,能讓使用者以 Tab 鍵或快捷鍵操作對話盒的控制項。
DS_FIXEDSYS8h用 SYSTEM_FIXED_FONT 代替內定的 SYSTEM_FONT,亦即使用固定寬度的字形作為對話盒字形。
DS_LOCALEDIT20h只能用於 16 位元程式,可使對話盒編輯框的資料在程式的資料區段內。
DS_MODALFRAME80h建立模式對話盒外框,常與 WS_CAPTION、WS_SYSMENU 合用,分別顯示標題欄與系統選單。
DS_NOFAILCREATE10h即使錯誤發生,也建立對話盒。例如對話盒內的控制項無法建立,或編輯框無法配置記憶體,系統仍建立對話盒。
DS_NOIDLEMSG100h當對話盒禁止對話盒收到 WM_ENTERIDLE 訊息。
DS_SETFONT40h程式能把 WM_SETFONT 訊息傳送給對話盒內的控制項,變更控制項的字形。但是如果對話盒具有 DS_SETFONT 風格的話,對話盒的視窗函式也能收到 WM_SETFONT 訊息,使對話盒能有機會改變控制項的大小,以顯示所有文字。
DS_SETFOREGROUND200h建立具有此風格的對話盒時,系統會呼叫 SetForegroundWindow,而使對話盒顯示在螢幕最上層,在需要讓使用者得知重要訊息時,特別有用。
DS_SHELLFONT48h相當於 DS_SETFONT | DS_FIXEDSYS,指示對話盒使用系統字形。
DS_SYSMODAL2h此風格只在 16 位元的系統使用,現已廢止。此風格相當於 WS_EX_TOPMOST 延伸風格。

註三:常見的延伸風格

風格數值說  明
WS_EX_ACCEPTFILES10h使視窗能接收滑鼠拖放的檔案。
WS_EX_APPWINDOW40000h 當視窗可以在螢幕上顯現時,能強制使視窗壓在工作列上。
WS_EX_CLIENTEDGE200h 使視窗具有凹陷的邊框,好像在三維空間一樣。
WS_EX_COMPOSITED2000000h 系統繪製此視窗的子視窗時,用 double-buffering 方式由下而上繪製。
WS_EX_CONTEXTHELP400h 在視窗的標題列包含問號。當使用者按一下問號,游標會變為有指標的問號。如果使用者再按一下子視窗,子視窗會收到 WM_HELP訊息。
WS_EX_CONTROLPARENT10000h 如果指定此延伸風格,使用者可以按 Tab 鍵或方向鍵依序讓各子視窗擁有輸入焦點。
WS_EX_DLGMODALFRAME1h雙邊框的視窗。
WS_EX_LAYERED80000h 建立 Layered Windows,必須要指定這種延伸風格。Layered Windows 一般是指不規則形狀或是透明的視窗。
WS_EX_LAYOUTRTL400000h 西伯來文或阿拉伯文版的 Windows 作業系統,能使水平座標原點在最右邊,越向左邊,座標值越大。
WS_EX_LEFT0視窗具有左邊對其的風格,這是內定值。
WS_EX_LEFTSCROLLBAR4000h 西伯來文或阿拉伯文版的 Windows 作業系統,能使垂直捲軸放在工作區的左邊。這個風格,在其他版本無作用。
WS_EX_LTRREADING0視窗內的文字由左向右閱讀,此為內定值。
WS_EX_MDICHILD40h建立 MDI 子視窗。
WS_EX_NOACTIVATE8000000h 此風格會使視窗顯示在螢幕最上層,但卻不具輸入焦點,亦即此視窗無法作用中,要使這種視窗作用,必須呼叫 SetActiveWindow 或 SetForegroundWindow。這種視窗也不會出現在工作列,除非和 WS_EX_APPWINDOW 合用。
WS_EX_NOINHERITLAYOUT100000h
WS_EX_NOPARENTNOTIFY4h 具有此延伸風格的視窗建立或關閉時,不會對父視窗發出 WM_PARENTNOTIFY 訊息。
S_EX_OVERLAPPEDWINDOW300h相當於 WS_EX_CLIENTEDGE 與 WS_EX_WINDOWEDGE 的結果。
WS_EX_PALETTEWINDOW188h相當於 WS_EX_WINDOWEDGE、WS_EX_TOOLWINDOW、WS_EX_TOPMOST 的結果。
WS_EX_RIGHT1000h這個延伸風格只有在西伯來文、阿拉伯文或其他支援閱讀方向的 Windows 版本適用,它會使視窗的文字由右向左排列。例如具有 WS_EX_RIGHT 的編輯框、靜態控件,分別和 ES_RIGHT、SS_RIGHT 風格的效果一樣。
WS_EX_RIGHTSCROLLBAR0 如果有捲軸,會放在工作區的右邊,這是內定的延伸風格。
WS_EX_RTLREADING2000h 這個延伸風格只有在西伯來文、阿拉伯文或其他支援閱讀方向的 Windows 版本適用,它會使視窗的文字由右向左排列。
WS_EX_STATICEDGE20000h使視窗具有三維邊框,通常用於不讓使用者輸入的控制項,例如靜態控制項。
WS_EX_TOOLWINDOW80hWS_EX_TOOLWINDOW 可以建立一個工具視窗,被作為浮動工具欄使用。工具視窗的標題欄比常規標題欄短,並且使用的視窗字體更小。如果工具視窗不具 WS_EX_APPWINDOW,那麼它就不會出現在工作列堙F當按下 ALT TAB 鍵後,也不會出現在工作切換程式列中。
WS_EX_TOPMOST8h 以這種風格產生的視窗會被系統放置在最上層,即使視窗沒有活動,也會保持在最上層。程式可以呼叫 SetWindowPos 來加入或移除此屬性。
WS_EX_TRANSPARENT20h 以這種風格產生的視窗會是透明的。也就是說,任何在這種視窗下的視窗不會被遮蔽。只有在所有同層級視窗 ( sibling windows ) 更新之後,具有這種風格的視窗才會收到 WM_PAINT 訊息。
WS_EX_WINDOWEDGE100h具有三維凸起邊框的視窗。

註四:簡潔的方式定義控制項

視窗類別
class name
控制元件
control type
名稱內定風格
STATIC LTEXT向左對齊的字串SS_LEFT,WS_GROUP
CTEXT向中對齊的字串SS_CENTER,WS_GROUP
RTEXT向右對齊的字串SS_RIGHT,WS_GROUP
ICON圖示控件SS_ICON
BUTTON PUSHBUTTON下壓式按鈕 BS_PUSHBUTTON,WS_TABSTOP
DEFPUSHBUTTON內定下壓式按鈕 BS_DEFPUSHBUTTON,WS_TABSTOP
CHECKBOX檢驗盒 BS_CHECKBOX,WS_TABSTOP
AUTOCHECKBOX自動檢驗盒 BS_AUTOCHECKBOX,WS_TABSTOP
RADIOBUTTON圓形按鈕 BS_RADIOBUTTON,WS_TABSTOP
AUTORADIOBUTTON自動圓形按鈕 BS_AUTORADIOBUTTON,WS_TABSTOP
GROUPBOX群組BS_GROUPBOX
STATE3三態檢驗盒 BS_3STATE,WS_TABSTOP
AUTO3STATE自動三態檢驗盒 BS_AUTO3STATE,WS_TABSTOP
EDITEDITTEXT 編輯框ES_LEFT,WS_BORDER,WS_TABSTOP
COMBOBOXCOMBOBOX 複合框CBS_SIMPLE,WS_TABSTOP
LISTBOXLISTBOX清單 LBS_NOTIFY,WS_BORDER
SCROLLBARSCROLLBAR捲軸 SBS_HORZ

回上一章回到首頁到下一章