2
當在Windows 7(也許是Vista)上任務欄中單擊時鐘時,會彈出一個彈出窗口,顯示日曆和時鐘(因此不是日期和時間調整窗口)。我如何自己打開此窗口(首選使用C#)?Windows 7左鍵單擊時鐘彈出
我希望timedate.cpl
會打電話給這個,但是這會打開日期和時間調整窗口。
當在Windows 7(也許是Vista)上任務欄中單擊時鐘時,會彈出一個彈出窗口,顯示日曆和時鐘(因此不是日期和時間調整窗口)。我如何自己打開此窗口(首選使用C#)?Windows 7左鍵單擊時鐘彈出
我希望timedate.cpl
會打電話給這個,但是這會打開日期和時間調整窗口。
要顯示時鐘,您需要將相應的窗口消息發送到托盤窗口。這可以通過使用Windows API函數SendMessage
來完成:
using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Text;
class ShowCalendar
{
private delegate bool EnumChildCallback(IntPtr hwnd,
ref IntPtr lParam);
[DllImport("User32.dll")]
private static extern bool EnumChildWindows(IntPtr hWndParent,
EnumChildCallback lpEnumFunc,
ref IntPtr lParam);
[DllImport("User32.dll")]
private static extern int GetClassName(IntPtr hWnd,
StringBuilder lpClassName,
int nMaxCount);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern IntPtr SendMessage(IntPtr hWnd,
UInt32 Msg,
IntPtr wParam,
IntPtr lParam);
[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr FindWindow(string lpClassName,
string lpWindowName);
[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr FindWindowEx(IntPtr hwndParent,
IntPtr hwndChildAfter,
string lpszClass,
string lpszWindow);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool GetWindowRect(IntPtr hWnd,
out RECT lpRect);
[StructLayout(LayoutKind.Sequential)]
private struct RECT
{
public int Left;
public int Top;
public int Right;
public int Bottom;
}
private static readonly string TrayWndClassName = "Shell_TrayWnd";
private static readonly string TrayNotifyWndClassName = "TrayNotifyWnd";
private static readonly string ClockWndClassName = "TrayClockWClass";
private static readonly uint WM_NCLBUTTONDOWN = 0x00A1;
private static readonly uint HTCAPTION = 2;
private static bool EnumChildProc(IntPtr hwndChild, ref IntPtr lParam)
{
StringBuilder className = new StringBuilder(128);
GetClassName(hwndChild, className, 128);
if (className.ToString() == ClockWndClassName)
{
lParam = hwndChild;
return false;
}
return true;
}
static void Main(string[] args)
{
IntPtr hWndTray = FindWindow(TrayWndClassName, string.Empty);
if (hWndTray == IntPtr.Zero)
{
throw new Win32Exception();
}
IntPtr hWndTrayNotify = FindWindowEx(hWndTray,
IntPtr.Zero,
TrayNotifyWndClassName,
string.Empty);
if (hWndTrayNotify == IntPtr.Zero)
{
throw new Win32Exception();
}
// search clock window
EnumChildCallback cb = new EnumChildCallback(EnumChildProc);
IntPtr hWndClock = IntPtr.Zero;
EnumChildWindows(hWndTray, cb, ref hWndClock);
if (hWndClock == IntPtr.Zero)
{
throw new Win32Exception();
}
// get clock window position
RECT rect;
if (!GetWindowRect(hWndClock, out rect))
{
throw new Win32Exception();
}
// send click, lParam contains window position
IntPtr wParam = new IntPtr(HTCAPTION);
IntPtr lParam = new IntPtr(rect.Top << 16 | rect.Left);
SendMessage(hWndTray, WM_NCLBUTTONDOWN, wParam, lParam);
}
}
日Thnx答覆,但我想類似的東西也和它有兩個問題: 1)時鐘必須是可見的(在系統打開時鐘關閉圖標不會顯示彈出窗口)。 2)我想在其他地方顯示彈出窗口(第二個屏幕)。 – jerone 2010-07-28 20:16:59
我想一旦窗口在那裏,你可以在句柄上調用SetWindowPos – Sebastian 2013-11-29 23:10:17