2012-03-05 49 views
3

我在C#中做了一个弹跳屏幕保护程序。当只有一台显示器显示时,它可以很好地工作。但是,当我有双显示器显示时,边界无法正常工作。辅助监视器的位置似乎有效,似乎没有右边界(辅助屏幕位于右侧)。C#辅助监视器边界问题

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Windows.Forms; 

namespace LIUScreensaver 
{ 
    static class Program 
    { 
     /// <summary> 
     /// The main entry point for the application. 
     /// </summary> 
     [STAThread] 
     static void Main(string[] args) 
     { 
      Application.EnableVisualStyles(); 
      Application.SetCompatibleTextRenderingDefault(false); 
      if (args.Length > 0) 
      { 
       string firstArg = args[0].ToLower().Trim(); 
       string secondArg = null; 

       //handle cases where arguments are separated by colon 
       if (firstArg.Length > 2) 
       { 
        secondArg = firstArg.Substring(3).Trim(); 
        firstArg = firstArg.Substring(0, 2); 
       } 
       else if (args.Length > 1) 
       { 
        secondArg = args[1]; 
       } 

       if (firstArg == "/c") 
       { 
        MessageBox.Show("This screensaver does not allow configuration changes"); 
       } 
       else if (firstArg == "/p") 
       { 
        if (secondArg == null) 
        { 
         MessageBox.Show("Sorry, but there was an error.", "Screensaver", MessageBoxButtons.OK, 
          MessageBoxIcon.Error); 
         return; 
        } 
        IntPtr preview = new IntPtr(long.Parse(secondArg)); 
        Application.Run(new ScreensaverForm(preview)); 
       } 
       else if (firstArg == "/s") 
       { 
        ShowScreenSaver(); 
        Application.Run(); 
       } 
       else 
       { 
        MessageBox.Show("Invalid command line argument. \"" + firstArg + "\" is not a valid ", "Screensaver", 
         MessageBoxButtons.OK, MessageBoxIcon.Exclamation); 
       } 

      } 
      else 
      { 
       MessageBox.Show("There has been an error displaying the screensaver. Please report this issue."); 
      } 
     } 
     public static void ShowScreenSaver() 
     { 
      //creates form on each display 
      int i = 0; 
      Screen[] screen = Screen.AllScreens; 
      for (i = 0; i < screen.Length; i++) 
      { 
       ScreensaverForm screensaver = new ScreensaverForm(screen[i].Bounds); 
       screensaver.Show(); 
      } 
     } 
    }  
} 

//屏保形式

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 
using System.Runtime.InteropServices; 

namespace LIUScreensaver 
{ 
public partial class ScreensaverForm : Form 
{ 

    [DllImport("user32.dll")] 
    static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent); 

    [DllImport("user32.dll")] 
    static extern int SetWindowLong(IntPtr hWnd, int nIndex, IntPtr dwNewLong); 

    [DllImport("user32.dll", SetLastError = true)] 
    static extern int GetWindowLong(IntPtr hWnd, int nIndex); 

    [DllImport("user32.dll")] 
    static extern bool GetClientRect(IntPtr hWnd, out Rectangle lpRect); 

    private Boolean previewMode = false; 
    private int mouseX = 0, mouseY = 0; 
    private int imgX = 0, imgY = 0; 
    private Boolean bot = true, left = true, right = false, top = false; 
    Point p; 

    //constructor with no arguments 
    public ScreensaverForm() 
    { 
     InitializeComponent(); 
    } 

    //constructor with bound arguments 
    public ScreensaverForm(Rectangle Bounds) 
    { 
     InitializeComponent(); 
     this.Bounds = Bounds; 
    } 

    //preview constructor 
    public ScreensaverForm(IntPtr preview) 
    { 
     InitializeComponent(); 

     SetParent(this.Handle, preview); 

     SetWindowLong(this.Handle, -16, new IntPtr(GetWindowLong(this.Handle, -16) | 0x40000000)); 

     Rectangle parentRec; 
     GetClientRect(preview, out parentRec); 
     Size = parentRec.Size; 
     Location = new Point(0, 0); 

     txtLabel.Font = new System.Drawing.Font("Arial", 6); 

     previewMode = true; 
    } 

    //form load 
    private void ScreensaverForm_Load(object sender, EventArgs e) 
    { 
     Cursor.Hide(); 
     TopMost = true; 
     System.Drawing.Color background = System.Drawing.ColorTranslator.FromHtml("#002668"); 
     this.BackColor = background; 

     moveTimer.Interval = 1; 
     moveTimer.Tick += new EventHandler(moveTimer_Tick); 
     moveTimer.Start(); 
    } 

    // 
    //----------------------------------------------------------------------------------------------------- 
    //The following code ends the application and exits the screensaver 
    private void ScreensaverForm_KeyPress(object sender, KeyPressEventArgs e) 
    { 
     if (!previewMode) 
     { 
      Application.Exit(); 
     } 
    } 

    private void ScreensaverForm_MouseMove(object sender, MouseEventArgs e) 
    { 
     if (!previewMode) 
     { 
      if (mouseX == 0) 
      { 
       mouseX = e.X; 
       mouseY = e.Y; 
      } 

      if ((mouseX - e.X) > 5 || (mouseY - e.Y) > 5) 
      { 
       Application.Exit(); 
      } 
     } 
    } 

    private void ScreensaverForm_MouseClick(object sender, MouseEventArgs e) 
    { 
     if (!previewMode) 
     { 
      Application.Exit(); 
     } 
    } 

    // 
    // 
    //timer to bounce the image across the screen 
    private void moveTimer_Tick(object sender, System.EventArgs e) 
    { 
     // Move text to new location 
     bounce(); 
    } 

    //function that moves the image 
    private void bounce() 
    { 

     //Checks boundaries 
     if (txtLabel.Location.Y + txtLabel.Image.Height - this.Bounds.Bottom>= 0) 
     { 
      top = true; 
      bot = false; 
     } 
     if (txtLabel.Location.X + txtLabel.Image.Width - this.Bounds.Right >= 0) 
     { 
      right = false; 
      left = true; 
     } 
     if (txtLabel.Location.X <= this.Bounds.Left) 
     { 
      right = true; 
      left = false; 
     } 

     if (txtLabel.Location.Y <= this.Bounds.Top) 
     { 
      top = false; 
      bot = true; 
     } 

     //moves image 
     if (bot == true) 
     { 
      if (right == true) 
      { 
       ++imgX; 
       ++imgY; 

       p.X = imgX; 
       p.Y = imgY; 
       txtLabel.Location = p; 
      } 
      else if (left == true) 
      { 
       --imgX; 
       ++imgY; 

       p.X = imgX; 
       p.Y = imgY; 
       txtLabel.Location = p; 
      } 

     } 
     if (top == true) 
     { 
      if (right == true) 
      { 
       ++imgX; 
       --imgY; 

       p.X = imgX; 
       p.Y = imgY; 
       txtLabel.Location = p; 
      } 
      else if (left == true) 
      { 
       --imgX; 
       --imgY; 

       p.X = imgX; 
       p.Y = imgY; 
       txtLabel.Location = p; 
      } 
     } 

     Invalidate(); 
    } 

} 

} 

回答

2

问题是标签的位置是相对于它的上,而边界您比较它也可在所有显示器的绝对位置监视器的位置。

因此,如果主监视器的边界是Top: 0, Bottom: 900, Left: 0, Right: 1600 辅助监视器的边界可能类似于Top: 0, Bottom: 900, Left: 1600, Right: 3200。虽然辅助显示器上标签的Location将返回其相对于辅助显示器的位置,例如Location.X: 200, Location.Y: 300

您需要更改bounce方法以使比较仅使用绝对坐标或仅使用相对坐标。

下面是比较代码修改为使用监视器上标签的相对位置;

if (txtLabel.Location.Y + txtLabel.Image.Height - (this.Bounds.Bottom - this.Bounds.Top) >= 0) 
{ 
    top = true; 
    bot = false; 
} 
if (txtLabel.Location.X + txtLabel.Image.Width - (this.Bounds.Right - this.Bounds.Left) >= 0) 
{ 
    right = false; 
    left = true; 
} 
// in relative coordinates left is always 0 
if (txtLabel.Location.X <= 0) 
{ 
    right = true; 
    left = false; 
} 
// in relative coordinates top is always 0 
if (txtLabel.Location.Y <= 0) 
{ 
    top = false; 
    bot = true; 
}