キーワード:ダイアログ、ダイアログ、resizable
1。問題が発生しました
問題はstanley_xuに由来し、閉じるボタンのみを取得することを望んでいます(それも役立つことができます)、左上にプログラムのアイコンはなく、ダイアログボックスはウィンドウサイズを変更できます。
ボーダーシルとボーダリコンのプロパティは、VCLのTFORM向けに設定されており、ウィンドウスタイルの設定を簡素化します(そうでなければ、SetWindowlongやGetWindowlongなどのAPI関数を呼び出す必要があります)。 TformborderstyleとTbordericonの定義と説明は次のとおりです。
価値の意味
bsdialogは、標準的なダイアログボックスの境界線を変更できません
bssingleは再配置できません
bsnoneNotresizable
BSSizais Standard Resizable Border
BSSINGLEのようなbstoolwindowですが、キャプションは小さくなります
bssizetoolwinは、より小さなキャプションを備えたbssizeableのようなものです
タイプtbordericon =(bisystemmenu、biminimize、bimaximize、bihelp);
tbordericons = tbordericonのセット。
価値の意味
bisystemmenuフォームには、コントロールメニュー(システムメニューとも呼ばれます)があります。
フォームには最小化ボタンがあります
フォームには最大化ボタンがあります
BorderStyleがBSDialogまたはBiminimizeとBimaximizeが除外されている場合、フォームのタイトルバーに疑問符が表示され、Crhelpにカーソルが変更されます。
明らかに、BorderstyleとBordericonsは一般的なニーズを満たすことしかできず、サイズを変更できるダイアログボックスを実装することは不可能です。
一般的に言えば、最大化できないがサイズを変更できるウィンドウを取得したい場合は、ボーダーシルをbssizaibleに設定し、bordericonsのビミニミスを削除してバイマックス化します。結果は次のようになります。ウィンドウは変更できますが、左上隅のアイコン:
図1アイコン付きダイアログボックス
左上隅にアイコンがあることに注意してください。
私たちの目標は、以下の2つの効果です。
図2 [ファイルを開く]ダイアログボックス
図3 [フォルダー]ダイアログボックスを参照します
2。問題の半分が解決します
私はMSDNを検索し、サイズを変更できるプロパティページを設計する方法を教える記事を見つけました(MFCでは、CPROPERTYSHEETはCPROPERTYPAGEサブページとして表示されます。シート、記事で導入された方法は、プロパティページが作成される前にウィンドウスタイルを変更し、wm_sizeメッセージを手動で処理することです。
int callback cmypropertysheet :: xmnpropsheetcallback(hwnd hwnd、uint message、lparam lparam)
{
extern int callback afxpropsheetcallback(hwnd、uint message、lparam lparam);
// XMN:MFCのコールバックを呼び出します
int nres = afxpropsheetcallback(hwnd、message、lparam);
スイッチ(メッセージ)
{
ケースPSCB_PRECREATE:
//独自のウィンドウスタイルを設定します
((lpdlgtemplate)lparam) - > style | =(ds_3dlook | ds_setfont
| ws_sysmenu |
壊す;
}
nresを返します。
}
同じ方法をVCLの形式に使用しようとしました。設計時にBorderStyleをBSDialogに設定し、CreateParamsメソッドを過負荷にします。しかし、その結果、ダイアログボックスは厚い境界線になり(WS_ThickFrameスタイルがあるため)、各境界に移動した後にマウスが自動的に変化する可能性があり、左上隅にアイコンはありませんが、ウィンドウはサイズを変更できません。 (追加されたWM_SIZEメッセージ処理プロセスはトリガーされていません)。何が問題なのですか?
図4まだ完全に満足していないダイアログボックス
3。問題を解決します
Forms.pasのソースコードを確認して、問題を見つけました。 TCUSTOMFORMのWM_NCCreateメッセージ処理プロセスには、ModifySystemMenu埋め込みプロセスがあります。これは、フォームのシステムメニューを変更するために使用されます。以下の赤いテキストには、「システムメニューをダイアログボックスのように見せる」と書かれていることに注意してください。コードの次の数文は、システムメニュー項目を「移動」と「閉じる」だけのポイントまで削除しました。
手順tcustomform.wmnccreate(var message:twmnccreate);
手順ModifySystemMenu;
var
sysmenu:hmenu;
始める
...
{システムメニューを変更して、それが存在するように見えるように}
sysmenu:= getsystemmenu(handle、false);
fborderStyle = bsdialogの場合
始める
{システムメニューをダイアログのように見せます。
移動して閉じる}
deletemenu(sysmenu、sc_tasklist、mf_bycommand);
deletemenu(sysmenu、7、mf_bypossion);
deletemenu(sysmenu、5、mf_bypossion);
deletemenu(sysmenu、sc_maximize、mf_bycommand);
deletemenu(sysmenu、sc_minimize、mf_bycommand);
deletemenu(sysmenu、sc_size、mf_bycommand);
deletemenu(sysmenu、sc_restore、mf_bycommand);
ENSEを終了します
...
終わり;
始める
継承;
setmenu(fmenu);
そうでない場合(CONPONENTSTATEでCSDESING)、ModifySystemMenu;
終わり;
したがって、問題は、「sc_size」が削除されているため、ウィンドウスタイルには変形があります。ws_thickframe(ウィンドウサイズは変更できます)がありますが、wm_sizeメッセージには応答しません(sc_sizeは削除されます)。
ソリューションは非常にシンプルです。独自のWM_NCCreateメッセージ処理プロセスを実装し、システムメニューを手動で変更します。
手順tzocdlgresizable.wmnccreate(var message:twmnccreate);
//次のコードは、form.pas line 4047、delphi 7 sp1からコピーされます。
手順ModifySystemMenu;
var
sysmenu:hmenu;
始める
sysmenu:= getsystemmenu(handle、false);
{システムメニューをダイアログのように見せます。
動き、サイズ、閉鎖コマンド}
deletemenu(sysmenu、sc_tasklist、mf_bycommand);
deletemenu(sysmenu、7、mf_bypossion);
//閉鎖コマンドの前にセパレーターを削除しないでください。
// deletemenu(sysmenu、5、mf_bypossion);
deletemenu(sysmenu、sc_maximize、mf_bycommand);
deletemenu(sysmenu、sc_minimize、mf_bycommand);
{サイズコマンドを削除しないでください、そうでなければ私たちは失う
ダイアログのサイズの能力。
// deletemenu(sysmenu、sc_size、mf_bycommand);
deletemenu(sysmenu、sc_restore、mf_bycommand);
終わり;
始める
{tcustomformのwm_nccreateハンドラーをスキップします
システムメニューからのサイズコマンド。}
継承されたDefulthandler(メッセージ);
//独自の方法でシステムメニューを処理します。
ModifySystemMenu;
終わり;
4。TZOCDLGRESIZABLEクラス
私がTFORMから継承されたクラスとしてカプセル化する最終的なソリューションは、図1と同じですtzocdlgresizable。
ところで、Tzocdlgresizableにsizegrip属性も追加しました。
図5アイコンなしのsizegripを備えたダイアログボックス
ダウンロード(exeおよびソースコード)
http://www.zocsoft.com/temp/resizable_dialog.rar
5。参考資料:
MSDN:変更可能なMFCプロパティシートの設計方法
引用アドレス:「Delphiのサイズを変更できるダイアログボックスの実装」