2015-12-07 7 views
12

मैं एक ऐसे ऐप पर काम कर रहा हूं जो स्क्रीन पर विंडोज़ को ग्रिड शैली में रखता है। विंडोज 10 पर इसे चलाने पर, खिड़कियों के बीच एक बड़ा अंतर है। आगे की जांच से पता चलता है कि GetWindowRect एक अदृश्य सीमा सहित अप्रत्याशित मूल्यों को वापस कर रहा है, लेकिन मैं इसे वास्तविक सीमाओं के साथ वास्तविक मूल्यों को वापस नहीं कर सकता।GetWindowRect "अदृश्य" सीमाओं सहित एक आकार देता है

1) This thread सुझाव देता है कि यह डिज़ाइन द्वारा है और आप Winver = 6 से लिंक करके इसे "ठीक" कर सकते हैं। मेरे वातावरण इस की अनुमति नहीं है, लेकिन मैं

2 को प्रभावित) उसी धागा भी DWMWA_EXTENDED_FRAME_BOUNDS साथ DwmGetWindowAttribute का उपयोग कर DWM है, जो काम करता है से वास्तविक निर्देशांक पाने के लिए पता चलता है कोई साथ 6 पीई MajorOperatingSystemVersion और MajorSubsystemVersion बदलते की कोशिश की है, लेकिन इसका मतलब है हर जगह बदल रहा है जो खिड़की निर्देशांक प्राप्त करता है। यह मूल्य को सेट करने की अनुमति नहीं देता है, जिससे हमें विंडो आकार सेट करने में सक्षम होने के लिए प्रक्रिया को उलट दिया जाता है।

3) This question बताता है कि इस प्रक्रिया में डीपीआई जागरूकता की कमी है। मेनिफेस्ट में डीपीआई जागरूकता ध्वज को सेट न करें, या SetProcessDpiAwareness पर कॉल करने से कोई परिणाम न हो।

4) एक सनकी पर, मैंने विंडोज विस्टा, 7, 8, 8.1 और 10 संगतता झंडे जोड़ने की कोशिश की है, और विंडोज़ थीम बिना किसी परिवर्तन के प्रकट होते हैं।

Screenshot of a "fullscreen" window with gaps all round यह विंडो 0x0, 1280x1024 पर ले जाया गया है, माना जाता है कि पूरी स्क्रीन भरने के लिए, और निर्देशांक को वापस पूछते समय, हमें वही मान मिलते हैं। विंडोज़ के पुराने संस्करणों पर सीमा को ध्यान में रखते हुए विंडो वास्तव में 14 पिक्सेल संकुचित है।

मैं विंडोज़ को असली खिड़की निर्देशांक के साथ काम करने के लिए कैसे मना सकता हूं?

+0

एक विस्तृत विंडो या छोटी सी खिड़की के लिए, निर्देशांक आप उम्मीद कर रहे हैं और निर्देशांक आप हो रही है क्या हैं? –

+0

@ बार्माक मुझे यह पसंद है जब मैं इसे 0x0 पर सेट करता हूं, तो विंडो 7x0 की बजाय शीर्ष बाईं ओर होती है, जो वास्तव में दिखाई दे रही है। स्क्रीनशॉट देखें। – Deanna

+0

क्या यह वीबी 6 या वीबी.नेट है? – IInspectable

उत्तर

11

विंडोज 10 में बाएं, दाएं और नीचे की पतली अदृश्य सीमाएं हैं, इसका उपयोग आकार बदलने के लिए माउस को पकड़ने के लिए किया जाता है। सीमाओं इस प्रकार दिखाई देंगे: 7,0,7,7 (बाएं, ऊपर, ठीक है, नीचे)

जब आप SetWindowPos फोन इस निर्देशांक पर खिड़की डाल करने के लिए:
0, 0, 1280, 1024

खिड़की उन सटीक निर्देशांक ले जाएगा, और GetWindowRect समान निर्देशांक वापस कर देगा। लेकिन नेत्रहीन, खिड़की यहाँ प्रतीत होता है:
7, 0, 1273, 1017

आप विंडो मूर्ख और यहाँ के बजाय जाने के लिए यह बता सकते हैं:
-7, 0, 1287, 1031

कि ऐसा करने के लिए, हम Windows 10 सीमा मोटाई मिलती है:

rect.left -= border.left; 
rect.top -= border.top; 
rect.right += border.left + border.right; 
rect.bottom += border.top + border.bottom; 

//new rect should be `-7, 0, 1287, 1031` 
:

RECT rect, frame; 
GetWindowRect(hwnd, &rect); 
DwmGetWindowAttribute(hwnd, DWMWA_EXTENDED_FRAME_BOUNDS, &frame, sizeof(RECT)); 

//rect should be `0, 0, 1280, 1024` 
//frame should be `7, 0, 1273, 1017` 

RECT border; 
border.left = frame.left - rect.left; 
border.top = frame.top - rect.top; 
border.right = rect.right - frame.right; 
border.bottom = rect.bottom - frame.bottom; 

//border should be `7, 0, 7, 7` 

फिर तो जैसे आयत ऑफसेट

जब तक कोई आसान समाधान न हो!

+0

और यह वही है जो मैं नहीं करना चाहता था, एक हैक यह पता लगाने के लिए कि ऑफ़सेट क्या है और वास्तविक मूल्यों को समायोजित करने के लिए हम उपयोग करते हैं। यद्यपि आपका कोई अन्य विकल्प नहीं है, लेकिन मैं अभी भी इसका उपयोग कर सकता हूं। – Deanna

+1

यह बस बेहतर हो जाता है ... यह विधि केवल विंडो के दिखाए जाने के बाद ही काम करती है :(तब तक, डीडब्लूएम फ़ंक्शन केवल 'GetWindowRect' के समान ही लौटाता है। – Deanna

+0

ओह, मैंने इसके बारे में नहीं सोचा था। मैं बस जा रहा हूँ इस उत्तर को हटाने के लिए। मैंने इसके साथ अन्य समस्याओं को देखा। ध्यान दें कि 'SetWindowPos' और' GetWindowRect' ठीक से काम कर रहे हैं। आपने सीमाओं के लिए कहा है और सिस्टम आपकी सीमाएं दे रहा है। केवल समस्या यह है कि सीमाएं विंडोज 10 में अदृश्य हैं, इसलिए ऐसा लगता है कि खिड़की गलत जगह पर है। विजुअल स्टूडियो आईडीई की अपनी टूल-विंडो है, जब टूल-विंडो डॉक किया गया है, तो यह कोई सीमा या कस्टम 'एनसी_PAINT' का उपयोग नहीं करता है; और जब इसकी टूल-विंडो चलती है, तो यह उपयोग करती है डिफ़ॉल्ट सीमाएं। मुझे लगता है कि आप कुछ ऐसा चाहते हैं? –

0

मैं विंडोज़ को वास्तविक खिड़की निर्देशांक के साथ काम करने के लिए कैसे समझा सकता हूं?

आप पहले से ही वास्तविक निर्देशांक के साथ काम कर रहे हैं। विंडोज 10 ने बस अपनी आंखों से सीमाओं को छिपाने के लिए चुना है। लेकिन फिर भी वे अभी भी वहां हैं। खिड़की के किनारों के पीछे आवास, आपका कर्सर आकार बदलने वाले कर्सर में बदल जाएगा, जिसका अर्थ है कि यह वास्तव में खिड़की पर भी है।

आप अपनी आँखें मैच के लिए क्या विंडोज आपको बता रहा है चाहते हैं, आप एयरो लाइट विषय का उपयोग करने वालों की सीमाओं को उजागर इतना है कि वे फिर से दिखाई दे रहे हैं की कोशिश कर सकते,:

http://winaero.com/blog/enable-the-hidden-aero-lite-theme-in-windows-10/

+1

यह निष्कर्ष है कि मैं आया था। विषय बदलना हालांकि एक विकल्प नहीं है क्योंकि यह व्यावसायिक रूप से उपलब्ध एप्लिकेशन है। अंतिम उपयोगकर्ताओं पर थीम को मजबूर करना आम तौर पर खराब अभ्यास माना जाता है :-) – Deanna

+1

मैं थीम को बदलने से सहमत हूं एक बुरा विचार है और कुछ ऐसा है जो मुझे अपने उपयोगकर्ताओं की आवश्यकता नहीं है। लेकिन वे अभी भी अंतराल के बारे में शिकायत करते हैं :( – mikew

-1

आप का जवाब कर सकते हैं WM_NCCALCSIZE संदेश, अदृश्य सीमा को हटाने के लिए WndProc का डिफ़ॉल्ट व्यवहार संशोधित करें।

this document और this document समझाते हैं, जब wParam> 0, अनुरोध पर wParam.Rgrc[0] खिड़की के नए निर्देशांक और जब प्रक्रिया रिटर्न शामिल के रूप में, प्रतिक्रिया wParam.Rgrc[0] नए ग्राहक आयत के निर्देशांक शामिल हैं।

golang कोड नमूना:

case win.WM_NCCALCSIZE: 
    log.Println("----------------- WM_NCCALCSIZE:", wParam, lParam) 

    if wParam > 0 { 
     params := (*win.NCCALCSIZE_PARAMS)(unsafe.Pointer(lParam)) 
     params.Rgrc[0].Top = params.Rgrc[2].Top 
     params.Rgrc[0].Left = params.Rgrc[0].Left + 1 
     params.Rgrc[0].Bottom = params.Rgrc[0].Bottom - 1 
     params.Rgrc[0].Right = params.Rgrc[0].Right - 1 
     return 0x0300 
    } 
संबंधित मुद्दे