求教在当前或指定窗口绘制网格(涉winapi)

PCCYC 2018-11-29 10:01:41
API已经导入。
代码也完成,但是界面没任何反应。
代码片段如下:

public Form1()
{
InitializeComponent();
}

[DllImport("user32.dll", EntryPoint = "FindWindow")]
private extern static IntPtr FindWindow(string lpClassName, string lpWindowName);

[DllImport("user32.dll")]
private static extern int GetWindowRect(IntPtr hwnd, out Rect lpRect);

public struct Rect
{
public int Left;
public int Top;
public int Right;
public int Bottom;
}


[StructLayout(LayoutKind.Sequential)]
struct PAINTSTRUCT
{
public IntPtr hdc;
public bool fErase;
public RECT rcPaint;
public bool fRestore;
public bool fIncUpdate;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public byte[] rgbReserved;
}

[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int Left, Top, Right, Bottom;

public RECT(int left, int top, int right, int bottom)
{
Left = left;
Top = top;
Right = right;
Bottom = bottom;
}

public RECT(System.Drawing.Rectangle r) : this(r.Left, r.Top, r.Right, r.Bottom) { }

public int X
{
get { return Left; }
set { Right -= (Left - value); Left = value; }
}

public int Y
{
get { return Top; }
set { Bottom -= (Top - value); Top = value; }
}

public int Height
{
get { return Bottom - Top; }
set { Bottom = value + Top; }
}

public int Width
{
get { return Right - Left; }
set { Right = value + Left; }
}

public System.Drawing.Point Location
{
get { return new System.Drawing.Point(Left, Top); }
set { X = value.X; Y = value.Y; }
}

public System.Drawing.Size Size
{
get { return new System.Drawing.Size(Width, Height); }
set { Width = value.Width; Height = value.Height; }
}

public static implicit operator System.Drawing.Rectangle(RECT r)
{
return new System.Drawing.Rectangle(r.Left, r.Top, r.Width, r.Height);
}

public static implicit operator RECT(System.Drawing.Rectangle r)
{
return new RECT(r);
}

public static bool operator ==(RECT r1, RECT r2)
{
return r1.Equals(r2);
}

public static bool operator !=(RECT r1, RECT r2)
{
return !r1.Equals(r2);
}

public bool Equals(RECT r)
{
return r.Left == Left && r.Top == Top && r.Right == Right && r.Bottom == Bottom;
}

public override bool Equals(object obj)
{
if (obj is RECT)
return Equals((RECT)obj);
else if (obj is System.Drawing.Rectangle)
return Equals(new RECT((System.Drawing.Rectangle)obj));
return false;
}

public override int GetHashCode()
{
return ((System.Drawing.Rectangle)this).GetHashCode();
}

public override string ToString()
{
return string.Format(System.Globalization.CultureInfo.CurrentCulture, "{{Left={0},Top={1},Right={2},Bottom={3}}}", Left, Top, Right, Bottom);
}
}

[DllImport("user32.dll")]
static extern IntPtr BeginPaint(IntPtr hwnd, out PAINTSTRUCT lpPaint);

[DllImport("user32.dll")]
static extern bool EndPaint(IntPtr hWnd, [In] ref PAINTSTRUCT lpPaint);

[DllImport("gdi32.dll")]
static extern bool MoveToEx(IntPtr hdc, int X, int Y, IntPtr lpPoint);

[DllImport("gdi32.dll")]
static extern bool LineTo(IntPtr hdc, int nXEnd, int nYEnd);

private delegate int HookProc(int code, IntPtr wParam, IntPtr lParam);
static IntPtr hHook;
IntPtr windowHandle =IntPtr.Zero;
uint processHandle;

HookProc PaintHookProcedure;

[System.Runtime.InteropServices.DllImport("user32.dll", EntryPoint = "SetWindowsHookEx", SetLastError = true)]


static extern IntPtr SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hMod, uint dwThreadId);

[System.Runtime.InteropServices.DllImport("user32.dll")]
static extern int CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);

private const int WM_PAINT = 15;
private const int WH_GETMESSAGE = 3;

[System.Runtime.InteropServices.DllImport("user32.dll")]
static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
Rect rect;
PAINTSTRUCT bPaintstruct;

[DllImport("kernel32.dll")]
static extern uint GetLastError();

[System.Runtime.InteropServices.DllImport("kernel32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
public static extern IntPtr GetModuleHandle(string lpModuleName);

[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
public static extern IntPtr GetForegroundWindow();

private void button1_Click(object sender, EventArgs e)
{

uint processHandle;


PaintHookProcedure = new HookProc(PaintHookProc);

Process curProcess = Process.GetCurrentProcess();


// windowHandle = FindWindow("Notepad", null);
// windowHandle = FindWindow(null, "计算器");
IntPtr hMod = System.Runtime.InteropServices.Marshal.GetHINSTANCE(typeof(Form1).Module);
windowHandle = GetForegroundWindow();
MessageBox.Show($"hMod={hMod},windowHandle={windowHandle}");


uint threadID = GetWindowThreadProcessId(windowHandle, out processHandle);

//获取尺寸
GetWindowRect(windowHandle, out rect);
var ret = GetLastError();
SetWindowsHookEx(WH_GETMESSAGE, PaintHookProcedure, GetModuleHandle(curProcess.MainModule.ModuleName), 0);

ret = GetLastError();
MessageBox.Show($"hMod={hMod.ToString()},GetLastError={ret.ToString()},threadID={threadID}" );
}
protected override void WndProc(ref Message message)
{
switch (message.Msg)
{
case WH_GETMESSAGE:
if (windowHandle != IntPtr.Zero)
{
ThreadPool.QueueUserWorkItem(o =>
{
//触发成功
MessageBox.Show(DateTime.Now.ToString("ssfffff"));
});
#region 绘制网格
var height = rect.Top;
var width = rect.Left;
var hdc = BeginPaint(windowHandle, out bPaintstruct);
for (int i = 20; i < width; i = i + 20)
{
MoveToEx(hdc, i, 0, IntPtr.Zero);
LineTo(hdc, i, height);
}

for (int j = 20; j < height; j = j + 20)
{
MoveToEx(hdc, 0, j, IntPtr.Zero);
LineTo(hdc, width, j);
}

EndPaint(windowHandle, ref bPaintstruct);
#endregion

}


break;
}
base.WndProc(ref message);
}




...全文
104 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
PCCYC 2018-11-29
  • 打赏
  • 举报
回复
引用 1 楼 良朋 的回复:
绘制网格其实完全可以不用API的

            //网格绘制
            pen = new Pen(Color.Green);
。。
谢了,XRate、YRate和brush能否给个初值,让我看看正常的效果。
良朋 2018-11-29
  • 打赏
  • 举报
回复
绘制网格其实完全可以不用API的


//网格绘制
pen = new Pen(Color.Green);
pen.DashPattern = new float[] { 3f, 5f };
//竖线
int n = width;
for (int i = 0; i < n; i += 30)
{
g.DrawLine(pen, new Point(i, 0), new Point(i, height));
//g.ResetTransform();
string txt = (Math.Round(i * XRate)).ToString();
g.DrawString(txt, this.Font, brush, i - 10, 3);
}
//横线
n = height;
for (int i = 0; i < n; i += 30)
{
g.DrawLine(pen, new Point(0, i), new Point(width, i));
//g.ResetTransform();
string txt = (Math.Round(i * YRate)).ToString();
StringFormat sf = new StringFormat();
sf.Alignment = StringAlignment.Near;
g.DrawString(txt, this.Font, brush, 3, i - 10, sf);
}

110,561

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧