?? 19. 多重文件界面.txt
字號(hào):
SendMessage (hwndClient, WM_MDISETMENU, (WPARAM) hMenuInit, (LPARAM) hMenuInitWindow) ;
DrawMenuBar (hwndFrame) ;
return 0 ;
case WM_DESTROY:
pRectData = (PRECTDATA) GetWindowLong (hwnd, 0) ;
HeapFree (GetProcessHeap (), 0, pRectData) ;
KillTimer (hwnd, 1) ;
return 0 ;
}
// Pass unprocessed message to DefMDIChildProc
return DefMDIChildProc (hwnd, message, wParam, lParam) ;
}
MDIDEMO.RC (摘錄)
//Microsoft Developer Studio generated resource script.
#include "resource.h"
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
// Menu
MDIMENUINIT MENU DISCARDABLE
BEGIN
POPUP "&File"
BEGIN
MENUITEM "New &Hello", IDM_FILE_NEWHELLO
MENUITEM "New &Rectangle", IDM_FILE_NEWRECT
MENUITEM SEPARATOR
MENUITEM "E&xit", IDM_APP_EXIT
END
END
MDIMENUHELLO MENU DISCARDABLE
BEGIN
POPUP "&File"
BEGIN
MENUITEM "New &Hello", IDM_FILE_NEWHELLO
MENUITEM "New &Rectangle", IDM_FILE_NEWRECT
MENUITEM "&Close", IDM_FILE_CLOSE
MENUITEM SEPARATOR
MENUITEM "E&xit", IDM_APP_EXIT
END
POPUP "&Color"
BEGIN
MENUITEM "&Black", IDM_COLOR_BLACK
MENUITEM "&Red", IDM_COLOR_RED
MENUITEM "&Green", IDM_COLOR_GREEN
MENUITEM "B&lue", IDM_COLOR_BLUE
MENUITEM "&White", IDM_COLOR_WHITE
END
POPUP "&Window"
BEGIN
MENUITEM "&Cascade\tShift+F5", IDM_WINDOW_CASCADE
MENUITEM "&Tile\tShift+F4", IDM_WINDOW_TILE
MENUITEM "Arrange &Icons", IDM_WINDOW_ARRANGE
MENUITEM "Close &All", IDM_WINDOW_CLOSEALL
END
END
MDIMENURECT MENU DISCARDABLE
BEGIN
POPUP "&File"
BEGIN
MENUITEM "New &Hello", IDM_FILE_NEWHELLO
MENUITEM "New &Rectangle", IDM_FILE_NEWRECT
MENUITEM "&Close", IDM_FILE_CLOSE
MENUITEM SEPARATOR
MENUITEM "E&xit", IDM_APP_EXIT
END
POPUP "&Window"
BEGIN
MENUITEM "&Cascade\tShift+F5", IDM_WINDOW_CASCADE
MENUITEM "&Tile\tShift+F4", IDM_WINDOW_TILE
MENUITEM "Arrange &Icons", IDM_WINDOW_ARRANGE
MENUITEM "Close &All", IDM_WINDOW_CLOSEALL
END
END
/////////////////////////////////////////////////////////////////////////////
// Accelerator
MDIDEMO ACCELERATORS DISCARDABLE
BEGIN
VK_F4, IDM_WINDOW_TILE, VIRTKEY, SHIFT, NOINVERT
VK_F5, IDM_WINDOW_CASCADE, VIRTKEY, SHIFT, NOINVERT
END
RESOURCE.H (摘錄)
// Microsoft Developer Studio generated include file.
// Used by MDIDemo.rc
#define IDM_FILE_NEWHELLO 40001
#define IDM_FILE_NEWRECT 40002
#define IDM_APP_EXIT 40003
#define IDM_FILE_CLOSE 40004
#define IDM_COLOR_BLACK 40005
#define IDM_COLOR_RED 40006
#define IDM_COLOR_GREEN 40007
#define IDM_COLOR_BLUE 40008
#define IDM_COLOR_WHITE 40009
#define IDM_WINDOW_CASCADE 40010
#define IDM_WINDOW_TILE 40011
#define IDM_WINDOW_ARRANGE 40012
#define IDM_WINDOW_CLOSEALL 40013
MDIDEMO支持兩種型態(tài)的非常簡(jiǎn)單的文件窗口:第一種窗口在它的顯示區(qū)域中央顯示"Hello, World!",另一種窗口顯示一系列隨機(jī)矩形(在原始碼列表和標(biāo)識(shí)符名中,它們分別叫做「Hello」文件和「Rect」文件)。這兩類文件窗口的菜單不同,顯示"Hello, World!"的文件窗口有一個(gè)允許使用者修改文字顏色的菜單。
三個(gè)菜單
現(xiàn)在讓我們先看看MDIDEMO.RC資源描述文件,它定義了程序所使用的三個(gè)菜單模板。
當(dāng)文件窗口不存在時(shí),程序顯示MdiMenuInit菜單,這個(gè)菜單只允許使用者建立新文件或退出程序。
MdiMenuHello菜單與顯示「Hello, World!」的文件窗口相關(guān)聯(lián)。「File」子菜單允許使用者打開任何一類新文件、關(guān)閉活動(dòng)文件或退出程序。「Color」子菜單允許使用者設(shè)定文字顏色。Window子菜單包括以平鋪或者重迭的方式安排文件窗口、安排文件圖標(biāo)或關(guān)閉所有窗口等選項(xiàng),這個(gè)子菜單也列出了它們建立的所有文件窗口。
MdiMenuRect菜單與隨機(jī)矩形文件相關(guān)聯(lián)。除了不包含「Color」子菜單外,它與MdiMenuHello菜單一樣。
RESOURCE.H表頭文件定義所有的菜單標(biāo)識(shí)符。另外,以下三個(gè)常數(shù)定義在MDIDEMO.C中:
#define INIT_MENU_POS 0
#define HELLO_MENU_POS 2
#define RECT_MENU_POS 1
這些標(biāo)識(shí)符說(shuō)明每個(gè)菜單模板中Windows子菜單的位置。程序需要這些信息來(lái)通知客戶窗口文件列表應(yīng)出現(xiàn)在哪里。當(dāng)然,MdiMenuInit菜單沒(méi)有Windows子菜單,所以如前所述,文件列表應(yīng)附加在第一個(gè)子菜單中(位置0)。不過(guò),實(shí)際上永遠(yuǎn)不會(huì)在此看到文件列表(在后面討論此程序時(shí),您可以發(fā)現(xiàn)這樣做的原因)。
定義在MDIDEMO.C中的IDM_FIRSTCHILD標(biāo)識(shí)符不對(duì)應(yīng)于菜單項(xiàng),它與出現(xiàn)在Windows子菜單上的文件列表中的第一個(gè)文件窗口相關(guān)聯(lián)。這個(gè)標(biāo)識(shí)符的值應(yīng)當(dāng)大于所有其它菜單ID的值。
程序初始化
在MDIDEMO.C中,WinMain是從注冊(cè)框架窗口和兩個(gè)子窗口的窗口類別開始的。窗口消息處理程序是FrameWndProc、HelloWndProc和RectWndProc。一般來(lái)說(shuō),這些窗口類別應(yīng)該與不同的圖標(biāo)相關(guān)聯(lián)。為了簡(jiǎn)單起見(jiàn),我們將標(biāo)準(zhǔn)IDI_APPLICATION圖標(biāo)用于框架窗口和子窗口。
注意,我們已經(jīng)定義了框架窗口類別的WNDCLASS結(jié)構(gòu)的hbrBackground字段為COLOR_APPWORKSPACE系統(tǒng)顏色。由于框架窗口的顯示區(qū)域被客戶窗口所覆蓋并且客戶窗口具有這種顏色,所以上面的定義不是絕對(duì)必要的。但是,在最初顯示框架窗口時(shí),使用這種顏色似乎要好一些。
這三種窗口類別中的lpszMenuName字段都設(shè)定為NULL。對(duì)「Hello」和「Rect」子窗口類別來(lái)說(shuō),這是很自然的。對(duì)于框架窗口類別,我在建立框架窗口時(shí)在CreateWindow函數(shù)中給出菜單句柄。
「Hello」和「Rect」子窗口的窗口類別將WNDCLASS結(jié)構(gòu)中的cbWndExtra字段設(shè)為非零值來(lái)為每個(gè)窗口配置額外空間,這個(gè)空間將用于儲(chǔ)存指向一個(gè)內(nèi)存塊的指針(HELLODATA和RECTDATA結(jié)構(gòu)的大小定義在MDIDEMO.C的開始處),這個(gè)內(nèi)存塊被用于儲(chǔ)存每個(gè)文件窗口特有的信息。
下一步,WinMain用LoadMenu載入三個(gè)菜單,并把它們的句柄儲(chǔ)存到整體變量中。呼叫三次GetSubMenu函數(shù)可獲得Windows子菜單(文件列表將加在它上面)的句柄,同樣也把它們儲(chǔ)存到整體變量中。LoadAccelerators函數(shù)加載加速鍵表。
在WinMain中呼叫CreateWindow建立框架窗口。在FrameWndProc中WM_CREATE消息處理期間,框架窗口建立客戶窗口。這項(xiàng)操作涉及到再一次呼叫函數(shù)CreateWindow。窗口類別被設(shè)定為MDICLIENT,它是預(yù)先注冊(cè)的MDI顯示區(qū)域窗口類別。在Windows中許多對(duì)MDI的支持被放入了MDICLIENT窗口類別中。顯示區(qū)域窗口消息處理程序作為框架窗口和不同文件窗口的中間層。當(dāng)呼叫CreateWindow建立顯示區(qū)域窗口時(shí),最后一個(gè)參數(shù)必須被設(shè)定為指向CLIENTCREATESTRUCT型態(tài)結(jié)構(gòu)的指針。這個(gè)結(jié)構(gòu)有兩個(gè)字段:
hWindowMenu是要加入文件列表的子菜單的句柄。在MDIDEMO中,它是hMenuInitWindow,是在WinMain期間獲得的。后面將看到如何修改此菜單。
idFirstChild是與文件列表中的第一個(gè)文件窗口相關(guān)聯(lián)的菜單ID。它就是IDM_FIRSTCHILD.
再讓我們回過(guò)頭來(lái)看看WinMain。MDIDEMO顯示新建立的框架窗口并進(jìn)入消息循環(huán)。消息循環(huán)與正常的循環(huán)稍有不同:在呼叫GetMessage從消息隊(duì)列中獲得消息之后,MDI程序把這個(gè)消息傳送給了TranslateMDISysAccel(以及TranslateAccelerator,如果像MDIDEMO程序一樣,程序本身也有菜單快捷鍵的話)。
TranslateMDISysAccel函數(shù)把可能對(duì)應(yīng)特定MDI快捷鍵(例如Ctrl-F6)的按鍵轉(zhuǎn)換成WM_SYSCOMMAND消息。如果TranslateMDISysAccel或TranslateAccelerator都傳回TRUE(表示某個(gè)消息已被這些函數(shù)之一轉(zhuǎn)換),就不能呼叫TranslateMessage和DispatchMessage。
注意傳遞到TranslateMDISysAccel和TranslateAccelerator的兩個(gè)窗口句柄:hwndClient和hwndFrame。WinMain函數(shù)通過(guò)用GW_CHILD參數(shù)呼叫GetWindow獲得hwndClient窗口句柄。
建立子窗口
FrameWndProc的大部分工作是用于處理通知菜單選擇的WM_COMMAND消息。與平時(shí)一樣,F(xiàn)rameWndProc中wParam參數(shù)的低字組包含著菜單ID。
在菜單ID的值為IDM_FILE_NEWHELLO和IDM_FILE_NEWRECT的情況下,F(xiàn)rameWndProc必須建立一個(gè)新的文件窗口。這涉及到初始化MDICREATESTRUCT結(jié)構(gòu)中的字段(大多數(shù)字段對(duì)應(yīng)于CreateWindow的參數(shù)),并將消息WM_MDICREATE發(fā)送給客戶窗口,消息的lParam參數(shù)設(shè)定為指向這個(gè)結(jié)構(gòu)的指針。然后由客戶窗口建立子文件窗口。(也可以使用CreateMDIWindow函數(shù)。)
MDICREATESTRUCT結(jié)構(gòu)中的szTitle字段一般是對(duì)應(yīng)于文件的文件名稱。樣式字段設(shè)定為窗口樣式WS_HSCROLL、WS_VSCROLL或這兩者的組合,以便在文件窗口中包括滾動(dòng)條。樣式字段也可以包括WS_MINIMIZE或WS_MAXIMIZE,以便在最初時(shí)以最小化或最大化狀態(tài)顯示文件窗口。
MDICREATESTRUCT結(jié)構(gòu)的lParam字段為框架窗口和子窗口共享某些變量提供了一種方法。這個(gè)字段可以設(shè)定為含有一個(gè)結(jié)構(gòu)的內(nèi)存塊的內(nèi)存句柄。在子文件窗口的WM_CREATE消息處理期間,lParam是一個(gè)指向CREATESTRUCT結(jié)構(gòu)的指針,這個(gè)結(jié)構(gòu)的lpCreateParams字段是一個(gè)指向用于建立窗口的MDICREATESTRUCT結(jié)構(gòu)的指針。
客戶窗口一旦接收到WM_MDICREATE消息就建立一個(gè)子文件窗口,并把窗口標(biāo)題加到用于建立客戶窗口的MDICLIENTSTRUCT結(jié)構(gòu)中所指定的子菜單的底部。當(dāng)MDIDEMO程序建立它的第一個(gè)文件窗口時(shí),這個(gè)子菜單就是「MdiMenuInit」菜單中的「File」子菜單。后面將看到這個(gè)文件列表將如何移到「MdiMenuHello」和「MdiMenuRect」菜單的「Windows」子菜單中。
菜單上可以列出9個(gè)文件,每個(gè)文件的前面是帶有底線的數(shù)字1至9。如果建立的文件窗口多于9個(gè),則這個(gè)清單后跟有「More Windows」菜單項(xiàng)。該項(xiàng)啟動(dòng)帶有清單方塊的對(duì)話框,清單方塊列出了所有文件。這種文件列表的維護(hù)是Windows MDI支持的最好特性之一。
關(guān)于框架窗口的消息處理
在把注意力轉(zhuǎn)移到子文件窗口之前,我們先繼續(xù)討論FrameWndProc的消息處理。
當(dāng)從「File」菜單中選擇「Close」時(shí),MDIDEMO關(guān)閉活動(dòng)子窗口。它通過(guò)把WM_MDIGETACTIVE消息發(fā)送給客戶窗口,而獲得活動(dòng)子窗口的句柄。如果子窗口以WM_QUERYENDSESSION消息來(lái)響應(yīng),那么MDIDEMO將WM_MDIDESTROY消息發(fā)送給客戶窗口,從而關(guān)閉子窗口。
處理「File」菜單中的「Exit」選項(xiàng)只需要框架窗口消息處理程序給自己發(fā)送一個(gè)WM_CLOSE消息。
處理Window子菜單的「Tile」、「Cascade」和「Arrange」選項(xiàng)是極容易的,只需把消息WM_MDITILE、WM_MDICASCADE和WM_MDIICONARRANGE發(fā)送給客戶窗口。
處理「Close All」選項(xiàng)要稍微復(fù)雜一些。FrameWndProc呼叫EnumChildWindows,傳送一個(gè)引用CloseEnumProc函數(shù)的指標(biāo)。此函數(shù)把WM_MDIRESTORE消息發(fā)送給每個(gè)子窗口,緊跟著發(fā)出WM_QUERYENDSESSION和WM_MDIDESTROY。對(duì)圖標(biāo)平鋪窗口來(lái)說(shuō)并不就此結(jié)束,用GW_OWNER參數(shù)呼叫GetWindow時(shí),傳回的非NULL值可以顯示出這一點(diǎn)。
FrameWndProc沒(méi)有處理任何由「Color」菜單中對(duì)顏色的選擇所導(dǎo)致的WM_COMMAND消息,這些消息應(yīng)該由文件窗口負(fù)責(zé)處理。因此,F(xiàn)rameWndProc把所有未經(jīng)處理的WM_COMMAND消息發(fā)送到活動(dòng)子窗口,以便子窗口可以處理那些與它們有關(guān)的消息。
框架窗口消息處理程序不予處理的所有消息都要送到DefFrameProc,它在框架窗口消息處理程序中取代了DefWindowProc。即使框架窗口消息處理程序攔截了WM_MENUCHAR、WM_SETFOCUS或WM_SIZE消息,這些消息也要被送到DefFrameProc中。
所有未經(jīng)處理的WM_COMMAND消息也必須送給DefFrameProc。具體地說(shuō),F(xiàn)rameWndProc并不處理任何WM_COMMAND消息,即使這些消息是使用者在Windows子菜單的文件列表中選擇文件時(shí)產(chǎn)生的(這些選項(xiàng)的wParam值是以IDM_FIRSTCHILD開始的)。這些消息要傳送到DefFrameProc,并在那里進(jìn)行處理。
注意框架窗口并不需要維護(hù)它所建立的所有文件窗口的窗口句柄清單。如果需要這些窗口句柄(如處理菜單上的「Close All」選項(xiàng)時(shí)),可以使用EnumChildWindows得到它們。
子文件窗口
現(xiàn)在看一下HelloWndProc,它是用于顯示「Hello, World!」的子文件窗口的窗口消息處理程序。
與用于多個(gè)窗口的窗口類別一樣,所有在窗口消息處理程序(或從該窗口消息處理程序中呼叫的任何函數(shù))中定義的靜態(tài)變量由依據(jù)該窗口類別建立的所有窗口共享。
只有對(duì)于每個(gè)唯一于窗口的數(shù)據(jù)才必須采用非靜態(tài)變量的方法來(lái)儲(chǔ)存。這樣的技術(shù)要用到窗口屬性。另一種方法(我使用的方法)是使用預(yù)留的內(nèi)存空間;可以在注冊(cè)窗口類別時(shí)將WNDCLASS結(jié)構(gòu)的cbWndExtra字段設(shè)定為非零值以便預(yù)留這部分內(nèi)存空間。
MDIDEMO程序使用這個(gè)內(nèi)存空間來(lái)儲(chǔ)存一個(gè)指標(biāo),這個(gè)指標(biāo)指向一塊與HELLODATA結(jié)構(gòu)大小相同的內(nèi)存塊。在處理WM_CREATE消息時(shí),HelloWndProc配置這塊內(nèi)存,初始化它的兩個(gè)字段(它們用于指定目前選中的菜單項(xiàng)和文字顏色),并用SetWindowLong將內(nèi)存指針儲(chǔ)存到預(yù)留的空間中。
當(dāng)處理改變文字顏色的WM_COMMAND消息(回憶一下,這些消息來(lái)自框架窗口消息處理程序)時(shí),HelloWndProc使用GetWindowLong獲得包含HELLODATA結(jié)構(gòu)的內(nèi)存塊的指針。利用這個(gè)結(jié)構(gòu),HelloWndProc清除原來(lái)對(duì)菜單項(xiàng)的選擇,設(shè)定所選菜單項(xiàng)為選中狀態(tài),并儲(chǔ)存新的顏色。
當(dāng)窗口變成活動(dòng)窗口或不活動(dòng)的時(shí)候,文件窗口消息處理程序都會(huì)收到WM_MDIACTIVATE消息(lParam的值是否為這個(gè)窗口的句柄表示了該窗口是活動(dòng)的還是不活動(dòng)的)。您也許還能記起MDIDEMO程序中有三個(gè)不同的菜單:當(dāng)無(wú)文件時(shí)為MdiMenuInit;當(dāng)「Hello」文件窗口是活動(dòng)窗口時(shí)為MdiMenuHello;當(dāng)「Rect」文件窗口為活動(dòng)窗口時(shí)為MdiMenuRect。
WM_MDIACTIVATE消息為文件窗口提供了一個(gè)修改菜單的機(jī)會(huì)。如果lParam中含有本窗口的句柄(意味著本窗口將變成活動(dòng)的),那么HelloWndProc就將菜單改為MdiMenuHello。如果lParam中包含另一個(gè)窗口的句柄,那么HelloWndProc將菜單改為MdiMenuInit。
HelloWndProc經(jīng)由把WM_MDISETMENU消息發(fā)送給客戶窗口來(lái)修改菜單,客戶窗口透過(guò)從目前菜單上刪除文件列表并把它添加到一個(gè)新的菜單上來(lái)處理這個(gè)消息。這就是文件列表從MdiMenuInit菜單(它在建立第一個(gè)文件時(shí)有效)傳送到MdiMenuHello菜單中的方法。在MDI應(yīng)用程序中不要用SetMenu函數(shù)改變菜單。
另一項(xiàng)工作涉及到「Color」子菜單上的選中旗標(biāo)。像這樣的程序選項(xiàng)對(duì)每個(gè)文件來(lái)說(shuō)都是不同的,例如,可以在一個(gè)窗口中設(shè)定黑色文字,在另一個(gè)窗口中設(shè)定紅色文字。菜單選中旗標(biāo)應(yīng)能反映出活動(dòng)窗口中選擇的選項(xiàng)。由于這種原因,HelloWndProc在窗口變成非活動(dòng)窗口時(shí)清除選中菜單項(xiàng)的選中旗標(biāo),而當(dāng)窗口變成活動(dòng)窗口時(shí)設(shè)定適當(dāng)菜單項(xiàng)的選中旗標(biāo)。
WM_MDIACTIVATE的wParam和lParam值分別是失去活動(dòng)和被啟動(dòng)窗口的句柄。窗口消息處理程序得到的第一個(gè)WM_MDIACTIVATE消息的lParam參數(shù)被設(shè)定為目前窗口的句柄。而當(dāng)窗口被消除時(shí),窗口消息處理程序得到的最后一個(gè)消息的lParam參數(shù)被設(shè)定為另一個(gè)值。當(dāng)使用者從一個(gè)文件切換到另一個(gè)文件時(shí),前一個(gè)文件窗口收到一個(gè)WM_MDIACTIVATE消息,其lParam參數(shù)為第一個(gè)窗口的句柄(此時(shí),窗口消息處理程序?qū)⒉藛卧O(shè)定為MdiMenuInit);后一個(gè)文件窗口收到一個(gè)WM_MDIACTIVATE消息,其lParam參數(shù)是第二個(gè)窗口的句柄(此時(shí),窗口消息處理程序?qū)⒉藛卧O(shè)定為MdiMenuHello或MdiMenuRect中適當(dāng)?shù)哪莻€(gè))。如果所有的窗口都關(guān)閉了,剩下的菜單就是MdiMenuInit。
當(dāng)使用者從菜單中選擇「Close」或「Close All」時(shí),F(xiàn)rameWndProc給子窗口發(fā)送一個(gè)WM_QUERYENDSESSION消息。HelloWndProc將顯示一個(gè)消息框并詢問(wèn)使用者是否要關(guān)閉窗口,以此來(lái)處理WM_QUERYENDSESSION和WM_CLOSE消息(在真實(shí)的應(yīng)用程序中,消息框會(huì)詢問(wèn)是否需要儲(chǔ)存文件)。如果使用者表示不能關(guān)閉窗口,那么窗口消息處理程序傳回0。
在WM_DESTROY消息處理期間,HelloWndProc釋放在WM_CREATE期間配置的內(nèi)存塊。
所有未經(jīng)處理的消息必須傳送到用于內(nèi)定處理的DefMDIChildProc(不是DefWindowProc)。不論子窗口消息處理程序是否使用了這些消息,有幾個(gè)消息必須被傳送給DefMDIChildProc。這些消息是:WM_CHILDACTIVATE、WM_GETMINMAXINFO、WM_MENUCHAR、WM_MOVE、WM_SETFOCUS、WM_SIZE和WM_SYSCOMMAND。
RectWndProc與HelloWndProc非常相似,但是它比HelloWndProc要簡(jiǎn)單一些(不含菜單選項(xiàng)并且無(wú)需使用者確認(rèn)是否關(guān)閉窗口),所以這里不對(duì)它進(jìn)行討論了。但應(yīng)該注意到,在處理WM_SIZE之后RectWndProc使用了「break」敘述,所以WM_SIZE消息被傳給DefMDIChildProc。
結(jié)束處理
在WinMain中,MDIDEMO使用LoadMenu加載資源描述檔中定義的三個(gè)菜單。一般說(shuō)來(lái),當(dāng)菜單所在的窗口被清除時(shí),Windows也要清除與之關(guān)聯(lián)的菜單。對(duì)于Init菜單,應(yīng)該清除那些沒(méi)有聯(lián)系到窗口的菜單。由于這個(gè)原因,MDIDEMO在WinMain的末尾呼叫了兩次DestroyMenu來(lái)清除「Hello」和「Rect」菜單。
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -