الكلمات المفتاحية : مربع حوار ، مربع حوار ، يمكن إصلاحه
1. المشكلة أثارت
تأتي المشكلة من Stanley_XU ، على أمل الحصول على زر الإغلاق فقط (يمكن أن يساعد أيضًا) ، لا يوجد أي رمز للبرنامج في أعلى اليسار وأن مربع الحوار قادر على تغيير حجم النافذة.
يتم تعيين خصائص BorderStyle و BoreDicons لـ TForm في VCL لتبسيط إعداد أنماط النوافذ (وإلا ، يجب استدعاء وظائف API مثل setWindowlong و getWindowlong). إن تعريف ووصف tformborderstyle و tbordericon على النحو التالي:
معنى القيمة
BSDIALOG غير قابلة للاختبار ؛
BSSINGLE غير قابلة للاختبار
BSNONENOTRESIBER
BSSISEBISIBLE القياسية الحدود القابلة للتشكيل
BStoolwindow مثل BSSingle ولكن مع تعليق أصغر
BSSIZETOOLWIN مثل BSSIZILE مع تعليق أصغر
اكتب tbordericon = (bisystemmenu ، biminimize ، bimaximize ، bihelp) ؛
tbordericons = مجموعة من tbordericon ؛
معنى القيمة
BisystemMenu يحتوي النموذج على قائمة تحكم (تُعرف أيضًا باسم قائمة النظام).
Biminimize يحتوي النموذج على زر الحد الأدنى
bimaximize يحتوي النموذج على زر تعظيم
Bihelp إذا تم استبعاد BordersTyle BSDialog أو biminimize و bimaximize ، تظهر علامة استفهام في شريط عنوان النموذج وعند النقر ، يتغير المؤشر إلى CRHELP ؛
من الواضح أن BorderStyle والحدود يمكن أن تلبي الاحتياجات العامة فقط ، ومن المستحيل تنفيذ مربعات الحوار التي يمكن أن تعدل الأحجام.
بشكل عام ، إذا كنت أرغب في الحصول على نافذة لا يمكن تعظيمها ولكن يمكنها تغيير الحجم ، فأنا أعزف من الحدود على bssizize ، وإزالة biminimize و bimaximize من الحدود ، والنتيجة مثل هذه: يمكن تعديل النافذة ، ولكن هناك أيقونة في الزاوية اليسرى العليا ،:
مربع الحوار الشكل 1 مع أيقونة
لاحظ أن هناك أيقونة في الزاوية اليسرى العلوية.
هدفنا هو اثنين من التأثيرات أدناه.
الشكل 2 مربع حوار ملف فتح
الشكل 3 مربع الحوار المجلد تصفح
2. يتم حل نصف المشكلة
لقد بحثت عن MSDN ووجدت مقالًا يعلمك كيفية تصميم صفحات الممتلكات التي يمكن أن تغير الحجم (في MFC ، تظهر CPROPERTYSHEET كصفحة فرعية لـ CPROPERTYPAGE ، والتي ترث من CDIALOG ولا يمكنها عادة تعديل الحجم) " ورقة ، الطريقة التي تم تقديمها في المقالة هي تعديل نمط النافذة قبل إنشاء صفحة الخصائص ، ثم معالجة رسالة 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)-> النمط | = (DS_3Dlook | DS_SETFONT
|
استراحة؛
}
إرجاع nres
}
لقد حاولت استخدام نفس الطريقة في شكل من أشكال VCL. اضبط BorderStyle على BSDialog عند التصميم ، ثم قم بتحميل طريقة CreateParams. ولكن النتيجة هي أن مربع الحوار يصبح حدودًا سميكة (لأنه يحتوي على نمط WS_THICKFRAME) ، يمكن أن يتغير الماوس تلقائيًا بعد الانتقال إلى كل حدود ، ولا يوجد أيقونة في الزاوية اليسرى العلوية ، لكن النافذة لا يمكنها تغيير حجمها (لم يتم تشغيل عملية معالجة الرسائل WM_SIZE المضافة). ما هي المشكلة؟
الشكل 4 مربع الحوار الذي لم يعد مرضيًا تمامًا بعد
3. حل المشكلة
راجعت رمز المصدر من forms.pas ووجدت المشكلة. هناك عملية تضمين ModifySystemMenu في عملية معالجة الرسائل WM_NCcreate لـ TCustomform ، والتي تُستخدم لتعديل قائمة النظام للنموذج. لاحظ أن النص الأحمر أدناه يقول "اجعل قائمة النظام تبدو وكأنها مربع حوار". حذفت الجمل القليلة التالية من التعليمات البرمجية عناصر قائمة النظام إلى النقطة التي "تتحرك" و "إغلاق" فقط.
الإجراء tcustomform.wmnccreate (var message: twmnccreate) ؛
الإجراء ModifySystemMenu ؛
var
Sysmenu: Hmenu ؛
يبدأ
...
{قم بتعديل قائمة النظام لتبدو أكثر مثل s'pose to}
sysmenu: = getSystemMenu (مقبض ، خطأ) ؛
إذا كان fborderstyle = bsdialog ثم
يبدأ
{اجعل قائمة النظام تبدو وكأنها مربع حوار يحتوي فقط
تحرك وإغلاق}
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) ؛
إنهاء آخر
...
نهاية؛
يبدأ
ورث
setmenu (fmenu) ؛
إذا لم يكن (CSDesigning في ComponentState) ثم 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 (مقبض ، خطأ) ؛
{اجعل قائمة النظام تبدو وكأنها مربع حوار يحتوي فقط
تحرك وحجم وإغلاق الأوامر}
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) ؛
نهاية؛
يبدأ
{تخطي معالج Tcustomform's WM_NCCreate ، الذي يزيل
أمر الحجم من قائمة النظام.}
defaulthandler الموروثة (رسالة) ؛
// التعامل مع قائمة النظام بطريقتنا الخاصة.
ModifySystemMenu ؛
نهاية؛
4
الحل النهائي الذي أتعامل معه كفئة موروثة من TForm. tzocdlgresible.
راجع للشغل: لقد أضفت أيضًا سمة SizeGrip إلى tzocdlgresivable.
الشكل 5 مربع الحوار مع sizegrip بدون أيقونة
تنزيل (exe والرمز المصدر)
http://www.zocsoft.com/temp/resizable_dialog.rar
5. المواد المرجعية:
MSDN: كيفية تصميم ورقة خاصية MFC يمكن إصلاحها
عنوان اقتباس: "تنفيذ مربع حوار يمكن أن يغير الحجم في دلفي"