将winform窗体钉在桌面上
本来想做一个日历小工具的,第一点是将工具钉在桌面上,第二是将窗体透明,为了好看嘛,可经过网上大量的查阅资料,最终两者都能一一实现,但不能一块儿实现,唉实在是遗憾,最后不得不选择了WPF。如果有哪位高手看到了我写的博文,有实现的方式的话,请指教!
但是查了半天,不能白查,所以把这些代码拿出来记上,万一那天要用呢。代码关键部分不算原创,都是从网上摘的。
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using CalendarLog.Core; using System.Runtime.InteropServices; namespace CalendarLog { public partial class CalendarForm : Form { LogForm logForm = null; public CalendarForm() { InitializeComponent(); SetToDeskTop(); } private void CalendarForm_Load(object sender, EventArgs e) { DateTime nowTime = DateTime.Now; this.numericUpDownYear.Value = nowTime.Year; this.numericUpDownMonth.Value = nowTime.Month; DrawCalendar(); } private void numericUpDownYear_KeyPress(object sender, KeyPressEventArgs e) { e.Handled = true; } private void numericUpDownMonth_KeyPress(object sender, KeyPressEventArgs e) { e.Handled = true; } private void numericUpDownYear_ValueChanged(object sender, EventArgs e) { DrawCalendar(); } private void numericUpDownMonth_ValueChanged(object sender, EventArgs e) { DrawCalendar(); } private void DrawCalendar() { this.panelCalendar.Controls.Clear(); this.panelCalendar.Controls.Add(CalendarManager.GetInstance().GetCalendar(Convert.ToInt32(numericUpDownYear.Value), Convert.ToInt32(numericUpDownMonth.Value))); } private void CalendarForm_MouseDown(object sender, MouseEventArgs e) { Win32.ReleaseCapture(); Win32.SendMessage(this.Handle, Win32.WM_SYSCOMMAND, Win32.SC_MOVE + Win32.HTCAPTION, 0);//窗体移动 } #region 将窗体钉在桌面上 private void SetToDeskTop() { try { if (Environment.OSVersion.Version.Major < 6) { base.SendToBack(); IntPtr hWndNewParent = Win32.FindWindow("Progman", null); Win32.SetParent(base.Handle, hWndNewParent); } else { IntPtr desktopHwnd = GetDesktopPtr(); IntPtr ownHwnd = base.Handle; IntPtr result = Win32.SetParent(ownHwnd, desktopHwnd); } } catch (ApplicationException exx) { MessageBox.Show(this, exx.Message, "Pin to Desktop"); } } private IntPtr GetDesktopPtr() { //http://blog.csdn.net/mkdym/article/details/7018318 // 情况一 IntPtr hwndWorkerW = IntPtr.Zero; IntPtr hShellDefView = IntPtr.Zero; IntPtr hwndDesktop = IntPtr.Zero; IntPtr hProgMan = Win32.FindWindow("ProgMan", null); if (hProgMan != IntPtr.Zero) { hShellDefView = Win32.FindWindowEx(hProgMan, IntPtr.Zero, "SHELLDLL_DefView", null); if (hShellDefView != IntPtr.Zero) { hwndDesktop = Win32.FindWindowEx(hShellDefView, IntPtr.Zero, "SysListView32", null); } } if (hwndDesktop != IntPtr.Zero) return hwndDesktop; // 情况二 while (hwndDesktop == IntPtr.Zero) {//必须存在桌面窗口层次 hwndWorkerW = Win32.FindWindowEx(IntPtr.Zero, hwndWorkerW, "WorkerW", null);//获得WorkerW类的窗口 if (hwndWorkerW == IntPtr.Zero) break;//未知错误 hShellDefView = Win32.FindWindowEx(hwndWorkerW, IntPtr.Zero, "SysListView32", null); if (hShellDefView == IntPtr.Zero) continue; hwndDesktop = Win32.FindWindowEx(hShellDefView, IntPtr.Zero, "SysListView32", null); } return hwndDesktop; } private void MainForm_Activated(object sender, EventArgs e) { if (Environment.OSVersion.Version.Major >= 6) { Win32.SetWindowPos(base.Handle, 1, 0, 0, 0, 0, Win32.SE_SHUTDOWN_PRIVILEGE); } } private void MainForm_Paint(object sender, PaintEventArgs e) { if (Environment.OSVersion.Version.Major >= 6) { Win32.SetWindowPos(base.Handle, 1, 0, 0, 0, 0, Win32.SE_SHUTDOWN_PRIVILEGE); } } #endregion private void labelOpenLog_Click(object sender, EventArgs e) { if (logForm == null) { logForm = new LogForm(); } if (!logForm.Visible) { logForm.Show(this); SetLogFormLocation(); } } private void CalendarForm_LocationChanged(object sender, EventArgs e) { SetLogFormLocation(); } private void SetLogFormLocation() { logForm.Location = new Point(this.Location.X + this.Width + 1, this.Location.Y); } } }
Win32类如下:
using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; namespace CalendarLog.Core { public class Win32 { public const int SE_SHUTDOWN_PRIVILEGE = 0x13; public const int WM_SYSCOMMAND = 0x0112; public const int SC_MOVE = 0xF010; public const int HTCAPTION = 0x0002;//无边框窗体移动 [DllImport("user32.dll")] public static extern IntPtr FindWindow(string lpClassName, string lpWindowName); [DllImport("user32.dll")] public static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent); [DllImport("user32.dll")] public static extern bool SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags); [DllImport("user32.dll")] public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow); [DllImport("user32.dll")] public static extern bool ReleaseCapture(); [DllImport("user32.dll")] public static extern bool SendMessage(IntPtr hwnd, int wMsg, int wParam, int lParam); } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律