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

首頁 > 編程 > Delphi > 正文

Delphi中實(shí)現(xiàn)可以更改大小的對話框

2019-11-18 18:01:29
字體:
供稿:網(wǎng)友
 

關(guān)鍵字:Dialog、對話框、resizable

1、問題的提出
問題來自Stanley_Xu,希望得到只有關(guān)閉按鈕(還可以有幫助),左上也沒有程序的圖標(biāo)并且能夠更改窗口大小的對話框。
VCL中為TForm設(shè)置了BorderStyle和BorderIcons屬性,用以簡化窗口樣式的設(shè)置(否則就要調(diào)用SetWindowLong和GetWindowLong等API函數(shù))。TFormBorderStyle和TBorderIcon的定義和說明如下:

Value          Meaning
bsDialog       Not resizable; standard dialog box border//不能改大小
bsSingle       Not resizable; single-line border
bsNone Not     resizable; no visible border line
bsSizeable     Standard resizable border
bsToolWindow   like bsSingle but with a smaller caption
bsSizeToolWin  like bsSizeable with a smaller caption

type TBorderIcon = (biSystemMenu, biMinimize, biMaximize, biHelp);
TBorderIcons = set of TBorderIcon;

Value          Meaning
biSystemMenu   The form has a Control menu (also known as a System menu).
biMinimize     The form has a Minimize button
biMaximize     The form has a Maximize button
biHelp         If BorderStyle is bsDialog or biMinimize and biMaximize are excluded, a question mark appears in the form's title bar and when clicked, the cursor changes to crHelp; otherwise,no question mark appears.

顯然,通過BorderStyle和BorderIcons只能夠滿足一般的需要,要實(shí)現(xiàn)能夠修改大小的對話框就有所力不能及了。
一般情況下,我要得到不能最大最小化但又可以更改大小的窗口,就把BorderStyle設(shè)置為bsSizeable,把BorderIcons的biMinimize和biMaximize去掉,結(jié)果象這樣:窗口可以修改大小,但左上角有圖標(biāo),:

VcLSizableDlg
圖 1 帶圖標(biāo)的對話框


注意左上角有圖標(biāo)。

而我們的目標(biāo)則是下面的兩種效果,左上角都沒有圖標(biāo),但窗口都可以修改大小。

OpenSaveDlg
圖 2 打開文件對話框

Browse4Folder

圖 3瀏覽文件夾對話框


2、問題解決一半
搜索了一下MSDN,找到一篇教你如何設(shè)計(jì)可以可更改大小的屬性頁的文章(在MFC中CPRopertySheet是作為CPropertyPage子頁出現(xiàn)的,后者從CDialog繼承而來,通常不能修改大小)《
How To Design a Resizable MFC Property Sheet》,文中介紹的方法是在屬性頁創(chuàng)建之前修改窗口樣式,然后手動處理WM_SIZE消息。

int CALLBACK CMyPropertySheet::XmnPropSheetCallback(HWND hWnd, UINT message, LPARAM lParam)
{
    extern int CALLBACK AfxPropSheetCallback(HWND, UINT message, LPARAM lParam);
    // XMN: Call MFC's callback
    int nRes = AfxPropSheetCallback(hWnd, message, lParam);

    switch (message)
    {
    case PSCB_PRECREATE:
       
// Set our own window styles
        ((LPDLGTEMPLATE)lParam)->style |= (DS_3DLOOK | DS_SETFONT
  | WS_THICKFRAME | WS_SYSMENU | WS_POPUP | WS_VISIBLE | WS_CAPTION);
        break;
    }
    return nRes;
}

我試著將同樣的方法用到VCL的一個(gè)Form中。在設(shè)計(jì)時(shí)把BorderStyle設(shè)置為bsDialog,然后重載CreateParams方法。但結(jié)果是對話框確實(shí)變成了厚邊框(因?yàn)橛蠾S_THICKFRAME樣式),鼠標(biāo)移動到各個(gè)邊框后能夠自動變化,左上角也沒有圖標(biāo),但窗口就是不能改變大小(添加的WM_SIZE消息處理過程沒有觸發(fā))。問題出在哪里呢?

HalfZoCDlgResizable

圖 4 還不能完全令人滿意的對話框

3、問題的解決
查了一翻Forms.pas的源代碼,發(fā)現(xiàn)了問題所在。TCustomForm的WM_NCCREATE消息處理過程中有一個(gè)ModifySystemMenu嵌入過程,用來修改Form的系統(tǒng)菜單。注意下面紅色文字說的是“使系統(tǒng)菜單看起來像對話框一樣”。接下來的幾句代碼就把系統(tǒng)菜單項(xiàng)刪得只剩下了“移動”和“關(guān)閉”。

procedure TCustomForm.WMNCCreate(var Message: TWMNCCreate);

procedure ModifySystemMenu;
var
    SysMenu: HMENU;
begin
    ……
   
{ Modify the system menu to look more like it's s'pose to }
    SysMenu := GetSystemMenu(Handle, False);
    if FBorderStyle = bsDialog then
    begin
        
{ Make the system menu look like a dialog which has only
        Move and Close }

        DeleteMenu(SysMenu, SC_TASKLIST, MF_BYCOMMAND);
        DeleteMenu(SysMenu, 7, MF_BYPOSITION);
        DeleteMenu(SysMenu, 5, MF_BYPOSITION);
        DeleteMenu(SysMenu, SC_MAXIMIZE, MF_BYCOMMAND);
        DeleteMenu(SysMenu, SC_MINIMIZE, MF_BYCOMMAND);
        DeleteMenu(SysMenu, SC_SIZE, MF_BYCOMMAND);
        DeleteMenu(SysMenu, SC_RESTORE, MF_BYCOMMAND);
    end else
    ……
end;

begin
    inherited;
    SetMenu(FMenu);
    if not (csDesigning in ComponentState) then ModifySystemMenu;
end;

所以,問題出在由于“SC_SIZE”被刪掉,窗口的樣式出現(xiàn)了畸形:有WS_THICKFRAME(可以修改窗口大小),但不響應(yīng)WM_SIZE消息(SC_SIZE被刪掉)。
解決的辦法很簡單:實(shí)現(xiàn)自己的WM_NCCREATE消息處理過程,手動修改系統(tǒng)菜單。


procedure TZoCDlgResizable.WMNCCreate(var Message: TWMNCCreate);

 //The following codes are copied from Form.pas line 4047, Delphi 7 sp1.
 procedure ModifySystemMenu;
 var
     SysMenu   : HMENU;
 begin
     SysMenu := GetSystemMenu(Handle, False);
     
{ Make the system menu look like a dialog which has only
  Move, Size and Close commands}
     DeleteMenu(SysMenu, SC_TASKLIST, MF_BYCOMMAND);
     DeleteMenu(SysMenu, 7, MF_BYPOSITION);
     
//Don't remove the separater before CLOSE command.
//   DeleteMenu(SysMenu, 5, MF_BYPOSITION);

     DeleteMenu(SysMenu, SC_MAXIMIZE, MF_BYCOMMAND);
     DeleteMenu(SysMenu, SC_MINIMIZE, MF_BYCOMMAND);
     
{ Don't remove the SIZE command, otherwise we'll lose the
  capability of resizing the Dialog. }
//   DeleteMenu(SysMenu, SC_SIZE, MF_BYCOMMAND);

     DeleteMenu(SysMenu, SC_RESTORE, MF_BYCOMMAND);
 end;

begin
   
{ Skip TCustomForm's WM_NCCREATE handler, which remove
    the SIZE command from the System Menu.}
    inherited DefaultHandler(Message);
   
//Dealing with the System Menu in our own way.
    ModifySystemMenu;
end;

4、TZoCDlgResizable類
最終的解決方案我封裝為一個(gè)繼承自TForm的類,效果如下,與圖1相同(如果想要圖2那樣的系統(tǒng)菜單則把調(diào)用ModifySystemMenu的行刪掉),使用的時(shí)候從TZoCDlgResizable繼承一個(gè)即可。
BTW:我還順手給TZoCDlgResizable加了個(gè)SizeGrip屬性,具體情況可以看代碼。


圖 5 沒有圖標(biāo)、可以修改大小、帶有SizeGrip的對話框

下載(exe和源代碼)
http://www.zocsoft.com/temp/Resizable_Dialog.rar

5、參考資料:

MSDN: How To Design a Resizable MFC Property Sheet

引用地址:《Delphi中實(shí)現(xiàn)可以更改大小的對話框



上一篇:Delphi下的接口編程學(xué)習(xí)筆記(原創(chuàng))

下一篇:如何在delphi5中實(shí)現(xiàn)對word文檔頁眉的設(shè)置?

發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
學(xué)習(xí)交流
熱門圖片

新聞熱點(diǎn)

疑難解答

圖片精選

網(wǎng)友關(guān)注

主站蜘蛛池模板: 宜良县| 鄯善县| 镇安县| 维西| 社旗县| 崇义县| 仁寿县| 武穴市| 高清| 开阳县| 沙坪坝区| 司法| 本溪| 法库县| 罗甸县| 泽普县| 马龙县| 达孜县| 上栗县| 高陵县| 渝中区| 嵊泗县| 新干县| 若尔盖县| 集安市| 镇康县| 盖州市| 宝鸡市| 铜川市| 化隆| 平罗县| 九寨沟县| 合作市| 宁强县| 江源县| 新晃| 开化县| 江油市| 磐石市| 信阳市| 泰宁县|