我正在尝试将C#代码片段转换为C ++。原始的C#代码会找到一个窗口,将其绘制为窗口时,它将渲染在桌面上的图标下方,因此基本上位于墙纸上,而不是墙纸上。但是,我似乎无法弄清楚如何从EnumWindows()
函数及其回调中获取特定的窗口句柄以进行绘制。
现在,我正在尝试传递强制转换为LPARAM
的窗口句柄指针:
HWND workerw;
EnumWindows((WNDENUMPROC)EnumWindowsProc, (LPARAM)&workerw);
然后在回调函数中,我将LPARAM参数转换回窗口句柄:
(HWND)workerw = FindWindowEx(0,hwnd,"WorkerW",0);
但是,当我运行程序时,什么也没有发生,这使我假设我没有绘制到正确的窗口。
这是整个文件:
#include <iostream>
#include <windows.h>
using namespace std;
BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam);
int main(int argc, char *argv[]){
Sleep(2000);
HWND progman = FindWindow("ProgMan", NULL);
// Send 0x052C to Progman. This message directs Progman to spawn a
// WorkerW behind the desktop icons. If it is already there, nothing
// happens.
SendMessageTimeout(progman,0x052C,0,0,SMTO_NORMAL,1000,nullptr);
HWND workerw;
EnumWindows((WNDENUMPROC)EnumWindowsProc, (LPARAM)&workerw);
HDC hdc = GetDC(workerw);
if (hdc != NULL){
TextOut(hdc, 20, 20, "hello world", 30);
}else{
cout << "error" << endl;
return 0;
}
RECT r = {0, 0, 1000, 1000};
RedrawWindow(workerw, &r, NULL, RDW_NOERASE | RDW_INVALIDATE | RDW_UPDATENOW);
ReleaseDC(workerw, hdc);
return 0;
}
BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM workerw)
{
HWND p = FindWindowEx(hwnd,0,"SHELLDLL_DefView",0);
if (p != 0){
// Gets the WorkerW Window after the current one.
(HWND)workerw = FindWindowEx(0,hwnd,"WorkerW",0);
}
return true;
}
这是我从here获得的原始C#文件的相关部分:
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace DrawBehindDesktopIcons
{
class Program
{
static void Main(string[] args)
{
// Fetch the Progman window
IntPtr progman = W32.FindWindow("Progman", null);
IntPtr result = IntPtr.Zero;
// Send 0x052C to Progman. This message directs Progman to spawn a
// WorkerW behind the desktop icons. If it is already there, nothing
// happens.
W32.SendMessageTimeout(progman,
0x052C,
new IntPtr(0),
IntPtr.Zero,
W32.SendMessageTimeoutFlags.SMTO_NORMAL,
1000,
out result);
IntPtr workerw = IntPtr.Zero;
// We enumerate all Windows, until we find one, that has the SHELLDLL_DefView
// as a child.
// If we found that window, we take its next sibling and assign it to workerw.
W32.EnumWindows(
new W32.EnumWindowsProc((tophandle, topparamhandle) =>
{
IntPtr p = W32.FindWindowEx(tophandle,
IntPtr.Zero,
"SHELLDLL_DefView",
IntPtr.Zero);
if (p != IntPtr.Zero)
{
// Gets the WorkerW Window after the current one.
workerw = W32.FindWindowEx(IntPtr.Zero,
tophandle,
"WorkerW",
IntPtr.Zero);
}
return true;
}),
IntPtr.Zero);
// We now have the handle of the WorkerW behind the desktop icons.
// We can use it to create a directx device to render 3d output to it,
// we can use the System.Drawing classes to directly draw onto it,
// and of course we can set it as the parent of a windows form.
// Get the Device Context of the WorkerW
IntPtr dc = W32.GetDCEx(workerw, IntPtr.Zero, (W32.DeviceContextValues)0x403);
if (dc != IntPtr.Zero)
{
for (int i = 0; i < 20000; i++)
{
// Create a Graphics instance from the Device Context
using(Graphics g = Graphics.FromHdc(dc))
{
g.FillRectangle(new SolidBrush(Color.White), 0, 0, 500, 500);
}
}
// make sure to release the device context after use.
W32.ReleaseDC(workerw, dc);
}
}
}
} // namespace DrawBehindDesktopIcons
当我编译并运行C#版本时,它可以正常工作。
当然,由于我完全不了解C#,因此很抱歉,我很可能错过了一些显而易见的东西。
我希望有人可以帮助我解决这个问题,这将使很多有趣的事情成为可能!
最后,我想使用面部检测和opencv在我的桌面背景中创建深度幻觉,这是一种实际的窗口之类的东西。