2010-06-25 9 views
7

मैं डेल्फी में एक स्क्रीनसेवर लिख रहा हूं। मैं चाहता हूं कि प्रत्येक मॉनिटर, फुलस्क्रीन पर एक TpresentationFrm प्रदर्शित करें।मैं द्वितीयक मॉनिटर पर एक फॉर्म कैसे प्रदर्शित कर सकता हूं?

program ScrTemplate; 

uses 
    ... 

{$R *.res} 

type 
    TScreenSaverMode = (ssmConfig, ssmDisplay, ssmPreview, ssmPassword); 

function GetScreenSaverMode: TScreenSaverMode; 
begin 
    // Some non-interesting code 
end; 

var 
    i: integer; 
    presentationForms: array of TpresentationFrm; 

begin 
    Application.Initialize; 
    Application.MainFormOnTaskbar := True; 

    case GetScreenSaverMode of 
    ssmConfig: 
     Application.CreateForm(TconfigFrm, configFrm); 
    ssmDisplay: 
     begin 
     SetLength(presentationForms, Screen.MonitorCount); 
     for i := 0 to high(presentationForms) do 
     begin 
      Application.CreateForm(TpresentationFrm, presentationForms[i]); 
      presentationForms[i].BoundsRect := Screen.Monitors[i].BoundsRect; 
      presentationForms[i].Visible := true; 
     end; 
     end 
    else 
    ShowMessage(GetEnumName(TypeInfo(TScreenSaverMode), integer(GetScreenSaverMode))); 
    end; 

    Application.Run; 
end. 

जब ssmDisplay कोड निष्पादित होने पर, दो रूपों वास्तव में बनाई गई हैं (हाँ, मैं ठीक दो पर नज़र रखता है है): इस उद्देश्य से, मैं निम्नलिखित (अधूरा) कार्यक्रम में लिखा है। लेकिन वे दोनों पहले मॉनीटर पर दिखाई देते हैं (इंडेक्स 0, लेकिन प्राथमिक नहीं)।

जब कोड के माध्यम से कदम, मुझे लगता है कि Screen.Monitors[i].BoundsRect सही हैं, लेकिन किसी कारण से रूपों गलत सीमा प्राप्त:

Watch Name       Value (TRect: Left, Top, Right, Bottom, ...) 
Screen.Monitors[0].BoundsRect (-1680, 0, 0, 1050, (-1680, 0), (0, 1050)) 
Screen.Monitors[1].BoundsRect (0, 0, 1920, 1080, (0, 0), (1920, 1080)) 

presentationForms[0].BoundsRect (-1680, 0, 0, 1050, (-1680, 0), (0, 1050)) 
presentationForms[1].BoundsRect (-1920, -30, 0, 1050, (-1920, -30), (0, 1050)) 

प्रथम रूप इच्छित स्थान मिलता है, लेकिन दूसरा नहीं है। X = 0 से 1920 तक जाने के बजाय, यह x = -1920 से 0 पर है, यानी यह पहले मॉनिटर पर पहले मॉनिटर पर दिखाई देता है। गलत क्या है? मैं जो चाहता हूं उसे पूरा करने के लिए उचित प्रक्रिया क्या है?

+0

आप उच्च डीपीआई पर नज़र रखता है पर समस्याओं होगा यदि आपके आवेदन उसके मेनिफ़ेस्ट में highdpi बारे में पता ध्वज शामिल नहीं है। इस मामले में, विंडोज एक गलत (वर्चुअलाइज्ड) बाध्य आयताकार की रिपोर्ट करेगा। – Ampere

उत्तर

7

रूप BoundRect का उपयोग कर सीमा सेट करने के लिए दृश्यमान होना चाहिए।

इस तरह लाइनों रिवर्स:

presentationForms[i].Visible := true; 
presentationForms[i].BoundsRect := Screen.Monitors[i].BoundsRect; 
+0

हां, मुझे बस 'लूप' में दो पंक्तियों को स्वैप करना होगा: पहले दृश्यता सेट करें, और फिर सीमाएं बदलें! –

2

स्पष्ट रूप से मैं समय-समय पर स्थिति निर्धारित करने का प्रयास करता हूं।

Application.CreateForm(TpresentationFrm, presentationForms[i]); 
presentationForms[i].Tag := i; 
presentationForms[i].Visible := true; 

साथ for पाश ब्लॉक बदलें और फिर लिखने

procedure TpresentationFrm.FormShow(Sender: TObject); 
begin 
    BoundsRect := Screen.Monitors[Tag].BoundsRect; 
end; 
0

आप उच्च डीपीआई पर नज़र रखता है पर समस्याओं होगा यदि आपके आवेदन उसके मेनिफ़ेस्ट में highdpi बारे में पता ध्वज शामिल नहीं है। इस मामले में, विंडोज एक गलत (वर्चुअलाइज्ड) बाध्य आयताकार की रिपोर्ट करेगा।

एक समाधान मैन्युअल रूप से स्क्रीन आप इस तरह चाहते हैं कि प्रपत्र स्थानांतरित करने के लिए होगा:

procedure MoveFormToScreen(Form: TForm; ScreenNo: Integer); 
begin 
Assert(Form.Position= poDesigned); 
Assert(Form.Visible= TRUE); 

Form.WindowState:= wsNormal; 
Form.Top := Screen.Monitors[ScreenNo].Top; 
Form.Left:= Screen.Monitors[ScreenNo].Left; 
Form.WindowState:= wsMaximized; 
end; 
संबंधित मुद्दे

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