2012-06-23 11 views
7

मेरे डेल्फी-7 आवेदन प्रदर्शित करता है:डेल्फी में TScreen का उपयोग करते हुए 7

Screen.DesktopWidth 
Screen.DesktopHeight 
Screen.Monitors[0].Width 
Screen.Monitors[0].Height 

और, हो, तो एक दूसरे पर नजर रखने का चयन किया है, यह भी:

Screen.Monitors[1].Width 
Screen.Monitors[1].Height 
पर मेरी WinXP प्रो पीसी में चल रहे एप्लिकेशन के साथ

, मैं कंट्रोल पैनल/डिस्प्ले/सेटिंग्स पर जाता हूं, और दूसरी मॉनीटर के लिए सेटिंग्स बदलता हूं (या तो इसे जोड़ या हटा देता हूं)।

मैं फिर 4 (या 6) पैरामीटर के नए मान प्रदर्शित करने के लिए रीफ्रेश बटन पर क्लिक करता हूं, और कुछ अप्रत्याशित होता है: स्क्रीन। डिस्कोटॉपविड्थ और स्क्रीन। डिस्कोटॉपहेइट सही नए मान दिखाता है, लेकिन दूसरे 2 के मान (या 4) पैरामीटर बहुत गलत हैं।

स्क्रीन की तरह। मॉनीटर [0] .Width = 5586935, जबकि यह 1680 होना चाहिए।

क्या डेल्फी 7 में टीस्क्रीन का उपयोग करने के लिए कुछ विशेष नियम हैं?

+1

मैं इसे अनुकरण नहीं कर सकता क्योंकि मेरे पास एक मॉनिटर और डेल्फी 200 है लेकिन मुझे लगता है कि समस्या मॉनिटर सूची रीफ्रेश के साथ हो सकती है (डेल्फी 200 9 में यह निजी प्रक्रिया 'स्क्रीन.गेट मॉनिटर' के माध्यम से किया जा रहा है)। मुझे लगता है कि जब आप अपना आवेदन पुनरारंभ करते हैं तो आपको सही मान मिलते हैं, है ना? और अगर मुझे यह सही याद है, शायद सर्टैक ने कहीं लिखा है कि 'स्क्रीन' उदाहरण को नष्ट करना और इसे फिर से बनाना सुरक्षित है। और यदि ऐसा है, तो निम्नलिखित को इन डेटा को रीफ्रेश करना चाहिए 'स्क्रीन। फ्री; स्क्रीन: = टीस्क्रीन। बनाएं (शून्य); ', लेकिन मुझे सच में नहीं पता कि यह क्रिया कितनी सुरक्षित है। – TLama

+0

क्या आप टीएमओनिटर इंस्टेंस स्क्रीन का संदर्भ ले रहे हैं। मॉनीटर [0] या क्या आप स्क्रीन प्राप्त कर रहे हैं। मॉनीटर [0] हर बार? –

+0

@TLama "मुझे लगता है कि जब आप अपना एप्लिकेशन पुनरारंभ करते हैं तो आपको सही मान मिलते हैं, है ना?" ये सही है । और जब मैं 4 (या 6) पैरामीटर प्रदर्शित करने वाले बयान ** से पहले ** ** ShowMessage कथन कहता हूं तो मुझे सही मान भी मिलते हैं। – AthenaAtDelphi

उत्तर

0

टलामा के लिए धन्यवाद, मुझे डेल्फी 7 में टीस्क्रीन समस्या के लिए एक समाधान मिला।

मूल कोड है कि 'की वजह से' समस्या:

LabMon1.Caption := ' Mon 1: ' + IntToStr (Screen.Monitors[0].Width) + 
        ' x ' + IntToStr (Screen.Monitors[0].Height); 

if (Screen.MonitorCount = 1) 
then LabMon2.Caption := ' Mon 2: -' 
else LabMon2.Caption := ' Mon 2: ' + IntToStr (Screen.Monitors[1].Width) + 
         ' x ' + IntToStr (Screen.Monitors[1].Height); 

मैं केवल इसे हल करने के लिए कोड का 1 पंक्ति जोड़ने के लिए किया था: के लिए

LabMon1.Caption := ' Mon 1: ' + IntToStr (Monitor.Width) + 
        ' x ' + IntToStr (Monitor.Height) ; 

LabMon1.Caption := ' Mon 1: ' + IntToStr (Screen.Monitors[0].Width) + 
        ' x ' + IntToStr (Screen.Monitors[0].Height); 

if (Screen.MonitorCount = 1) 
then LabMon2.Caption := ' Mon 2: -' 
else LabMon2.Caption := ' Mon 2: ' + IntToStr (Screen.Monitors[1].Width) + 
         ' x ' + IntToStr (Screen.Monitors[1].Height); 

तो फिर धन्यवाद TLama, अपने इस प्रश्न-धागे में महान योगदान!

+2

आपका स्वागत है! असल में, आपको 'मॉनिटर। विथथ' या 'मॉनिटर.हेइट'' का उपयोग करने की आवश्यकता नहीं है या कहीं भी उनके मान असाइन नहीं करते हैं। * ['मॉनिटर'] स्पर्श करें * (http://docwiki.embarcadero.com/Libraries/en/Vcl.Forms.TCustomForm.Monitor) संपत्ति जिसका गेटर 'स्क्रीन. मॉनिटर्स' सूची को संभालते समय अपडेट करता है उस सूची में प्राथमिक मॉनिटर नहीं मिला है। मैंने बस आपकी चौड़ाई जांच के लिए उपयोग किया है। यदि आप भाग्यशाली हैं और कंपाइलर इस तरह के कथन को खत्म नहीं करता है तो यह केवल 'मॉनीटर' का उपयोग करने के लिए पर्याप्त हो सकता है, जो कि मैंने जो वर्णन किया है, वह करने के लिए गेटर को क्या मजबूर कर सकता है। हालांकि अभी भी यह किसी भी तरह से गंदा तरीका है। – TLama

0

वही बात तब होती है जब आप अपने प्रोग्राम के दौरान उपयोगकर्ता को स्विच करते हैं। स्क्रीन स्विच करने के बाद। मॉनीटर सरणी में अमान्य मान होते हैं। हम कोड

Screen.MonitorFromWindow(0, mdNull); 

की इस पंक्ति का उपयोग स्क्रीन ऑब्जेक्ट को सूचियों को अपडेट करने के लिए मजबूर करने के लिए करते हैं।

0

मॉनिटर या यूएसबी डिस्प्ले डिवाइस को कनेक्ट या डिस्कनेक्ट करते समय टीएसस्क्रीन की रीफ्रेश समस्या (बग) की वजह से यहां आया। @ डेव 82 का जवाब मेरे लिए काम नहीं करता है। फ़ंक्शन का परिणाम MonitorFromWindow को TScreen ऑब्जेक्ट के अद्यतन को मजबूर करने के लिए एक और मान (अज्ञात/अमान्य मान) वापस करना होगा।

यह नीचे धोखा काम कर देता है:

uses 
multimon; 

(फार्म के) इंटरफ़ेस हिस्सा करने के लिए इस जोड़े

protected 
procedure WMDeviceChange(var Msg: TMessage); message WM_DEVICECHANGE; 
:

यकीन Multimon में ऐसा हो जाता है खंड का उपयोग करता है

इसे कार्यान्वयन में जोड़ें भाग (फॉर्म का)

function cheatMonitorFromWindow(hWnd: HWND; dwFlags: DWORD): HMONITOR; stdcall; 
    begin 
     // Does nothing, returns zero to force invalidate 
    Result:=0; 
    end; 

    procedure TForm1.WMDeviceChange(var Msg: TMessage); 
    var 
    iCurrDisplayCount : LongInt; 
    iNewDisplayCount  : LongInt; 
    pMonitorFromWinProc : TMonitorFromWindow; 

    begin 
    iCurrDisplayCount:=Screen.MonitorCount; 
    // Force monitor update, fix bug in customform, won't update at display change. 
    // This a hack/cheat to multimon MonitorFromWindow func, it's fakes the result. 
    // This is required to tell customform.getMonitor() to update the TScreen object. 
    pMonitorFromWinProc:=MonitorFromWindow;  // Backup pointer to dynamic assigned DLL func 
    MonitorFromWindow:=cheatMonitorFromWindow; // Assign cheat func 
    monitor;          // call the monitor property that calls customform.getMonitor and cheatfunc 
    MonitorFromWindow:=pMonitorFromWinProc;  // restore the original func 
    // ========== 
    iNewDisplayCount:=Screen.MonitorCount; 
    if(iCurrDisplayCount <> iNewDisplayCount) then 
    begin 
     // Display count change! 
    end; 
end; 

कस्टमफॉर्म के अंदर क्या होता है (Forms.pas में कोड)?

function TCustomForm.GetMonitor: TMonitor; 
var 
    HM: HMonitor; 
    I: Integer; 
begin 
    Result := nil; 
    HM := MonitorFromWindow(Handle, MONITOR_DEFAULTTONEAREST); 
    for I := 0 to Screen.MonitorCount - 1 do 
    if Screen.Monitors[I].Handle = HM then 
    begin 
     Result := Screen.Monitors[I]; 
     Exit; 
    end; 

    //if we get here, the Monitors array has changed, so we need to clear and reinitialize it 
    for i := 0 to Screen.MonitorCount-1 do 
    TMonitor(Screen.FMonitors[i]).Free; 
    Screen.FMonitors.Clear; 
    EnumDisplayMonitors(0, nil, @EnumMonitorsProc, LongInt(Screen.FMonitors)); 
    for I := 0 to Screen.MonitorCount - 1 do 
    if Screen.Monitors[I].Handle = HM then 
    begin 
     Result := Screen.Monitors[I]; 
     Exit; 
    end;  
end; 

उम्मीद है कि कोई इसे ढूंढने में मदद करता है। जब आप डिस्प्ले डिवाइस सेटिंग्स में परिवर्तन (संकल्प और अभिविन्यास) का पता लगाना चाहते हैं, तो इसके बजाय WM_DISPLAYCHANGE ईवेंट को पकड़ें।

संबंधित मुद्दे