พฤติกรรมการวาดภาพหน้าต่างไม่ถูกต้องในหน้าต่าง Qt แบบไร้กรอบ (win32)

ฉันมีแอปพลิเคชัน QML (ทดสอบด้วย QWidgets ปัญหาเดียวกัน) และเพื่อให้ไม่มีขอบเขต (แต่ยังคงรองรับคุณสมบัติ WM ดั้งเดิมเช่น aero snap ฯลฯ) ฉันติดตาม สิ่งนี้ โดยใช้ QAbstractNativeEventFilter และตอบสนองต่อสัญญาณ WM_NCCALSIZE ด้วยศูนย์:

switch(msg->message) {
  case WM_NCCALCSIZE:
    *r = 0;
    return 1;
    ...
}

ฉันยังตั้งค่าสถานะหน้าต่างบางตัวที่ไม่อยู่ใน Qt Namespace ด้วย

SetWindowLong(hwnd, GWL_STYLE, WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_CLIPSIBLINGS | WS_BORDER | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_THICKFRAME);

วิธีนี้ใช้ได้ดีจนกว่าฉันจะย้ายหรือปรับขนาดหน้าต่างซึ่งทำให้ Qt แสดงผลซ้ำ และพื้นที่ที่ไม่ได้ทาสี ความกว้าง ความกว้างของชื่อและเส้นขอบปรากฏขึ้น:

ก่อนที่จะย้าย/ปรับขนาด Before

หลังจากย้าย/ปรับขนาด After

ฉันยังพบวิธีแก้ไขปัญหานี้ด้วยการเพิ่มการตั้งค่าสถานะ FramelessWindowHint ใน Qt:

window->setFlags(Qt::FramelessWindowHint | Qt::WindowSystemMenuHint | Qt::Dialog);

แต่ตอนนี้ระยะขอบนี้เกิดขึ้นอีกครั้งเมื่อสถานะของหน้าต่างเปลี่ยนแปลง (ขยายใหญ่สุด ย่อเล็กสุด ...) ด้วยการบล็อกเหตุการณ์ WM_SIZE เช่น เมื่อ SIZE_MAXIMIZED เป็นพารามิเตอร์ ระยะขอบจะไม่ปรากฏ แต่ฉันก็ไม่สามารถขยายหน้าต่างให้ใหญ่สุดจาก Qt ได้ ซึ่งหมายความว่าเป็นปัญหาด้าน Qt

ฉันยังสังเกตด้วยการตรวจสอบรูปแบบหน้าต่างด้วย winspector ว่าหลังจากที่ฉันขยายใหญ่สุดแล้ว คุณสมบัติอะตอมใหม่จะปรากฏขึ้น:

ภาพหน้าจอ winspector

คุณช่วยฉันแก้ไขปัญหานี้ได้ไหม


person Community    schedule 06.02.2014    source แหล่งที่มา
comment
ขออภัย มันคือ Qt เวอร์ชัน 5.2   -  person    schedule 07.02.2014


คำตอบ (2)


ฉันคิดว่าการใช้ SetWindowLong บนตัวจัดการหน้าต่างของคุณและการใช้แอตทริบิวต์ Qt Window Flags/Qt Widget กำลังถามถึงปัญหา คุณสามารถไปดูแหล่งที่มาของ Qt เพื่อดูว่าเกิดอะไรขึ้นเมื่อประมวลผลแฟล็กหน้าต่างเหล่านั้น

เมื่อฉันสร้างหน้าต่างแบบไร้กรอบ ฉันมักจะทำเพื่อป้องกันการเคลื่อนย้ายและการปรับขนาด เพราะฉันจัดการทั้งหมดแยกกัน

ปัญหาหนึ่งที่ฉันพบคือเมื่อแป้นพิมพ์บนหน้าจอปรากฏขึ้นและเชื่อมต่อ มันจะปรับขนาดหน้าต่างของฉัน ดังนั้นนอกเหนือจากการโทร resize() ฉันยังต้องใช้ setFixedSize เพื่อป้องกันไม่ให้วิดเจ็ตของฉันถูกจัดการเมื่อระบบปฏิบัติการพยายามเปลี่ยนขนาดของหน้าต่าง

กล่าวอีกนัยหนึ่ง ฉันจะเพิ่มแอปพลิเคชัน wide QShortcut ฟังการหักแป้นพิมพ์ลัดและปรับขนาดหน้าต่างของคุณตามที่คุณต้องการเมื่อมันเกิดขึ้น หากคุณกำลังจัดการหน้าต่างแบบไร้กรอบ

หวังว่าจะช่วยได้

person phyatt    schedule 04.04.2014
comment
เหตุผลที่ฉันทำแบบนี้ก็คือ ฉันต้องการสนับสนุนฟีเจอร์ของแพลตฟอร์มดั้งเดิม เช่น การลากเพื่อปรับขนาด และการเปิดใช้งานเอฟเฟกต์เงา ในระหว่างนี้ ฉันจัดการเพื่อให้มันทำงานได้อย่างที่ตั้งใจไว้ แต่มันก็เหมือนกับวิธีแก้ปัญหาที่สกปรกมากกว่า แต่เป็นวิธีแก้ปัญหา - person ; 08.04.2014

ฉันสงสัยว่านี่เป็นข้อบกพร่องของการถ่ายทอดข้อความ Qt หรือไม่เพราะฉันพบปัญหาที่คล้ายกันซึ่งเกิดขึ้นบนหน้าต่างที่ซ้อนกัน หากคุณกดปุ่ม SIZE_MAXIMIZE หรือ SIZE_MINIMIZE ของหน้าต่างหลัก หน้าต่างลูกบางครั้งไม่สามารถรับข้อความ WM_SIZE ได้ ฉันคิดว่ามีวิธีแก้ไขประมาณสองวิธี: 1. แก้ไข Qt 2. แก้ไขให้ถูกต้อง

ที่นี่ฉันมีหน้าต่างลูกเรนเดอร์ OGL บางครั้งแม้แต่ข้อความ WM_SIZE ก็ส่งไม่ถูกต้อง นั่นคือ ถ้าคุณปรับขนาดหน้าต่างหลัก คุณจะได้รับส่วนหนึ่งของพื้นที่ไคลเอนต์เป็นสีดำ

ฉันเพียงใช้วิธีแก้ปัญหาง่ายๆ เพื่อแก้ไขปัญหานี้ โดยตรวจสอบขนาดปัจจุบันด้วยขนาดที่แคชไว้ และทำการปรับขนาดด้วยตนเอง

person Alex    schedule 01.08.2016