Я пытаюсь перевести часть кода 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;
}
И это соответствующая часть исходного файла 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, чтобы создать иллюзию глубины на фоне рабочего стола, что-то вроде окна.