D
volkard schrieb:
google mal nach
kvm multiplexer
und
mouse broadcaster
Und das bringt genau was ?
Das Problem bei dem Thema ist, dass Windows so ausgelegt ist, dass nur das aktive Fenster den Input bekommt.
Man kann zwar das Fenster jedesmal schnell wechseln, aber das finde ich sehr unschön.
Die letzte Möglichkeit wäre über Messages. Dafür hab ich schnell was zusammengestrickt:
#include <Windows.h>
#include <vector>
#include <string>
std::vector<HWND> handlesTemp;
BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
{
handlesTemp.push_back(hwnd);
return true;
}
std::vector<HWND> getAllWindows()
{
handlesTemp= std::vector<HWND>();
EnumWindows(EnumWindowsProc, 0);
return handlesTemp;
}
//Adds all windows which contain 'text' in their title to our list
void addWindow(std::vector<HWND>& windowsToUse, std::vector<HWND>& allWindows, std::string text)
{
std::vector<std::string> titles;
for(int i=0; i < allWindows.size(); i++)
{
int textLen = SendMessage(allWindows[i], WM_GETTEXTLENGTH, 0, 0);
char* text = new char[textLen+1];
//text[textLen] = '\0';
SendMessageA(allWindows[i], WM_GETTEXT, textLen+1, (LPARAM)text);
std::string title = text;
delete[] text;
titles.push_back(title);
}
for(int i=0; i < allWindows.size(); i++)
{
if(titles[i].find(text) != -1)
{
windowsToUse.push_back(allWindows[i]);
}
}
}
std::vector<HWND> windowsToUse;
LRESULT WINAPI WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case WM_CLOSE:
DestroyWindow(hWnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_KEYDOWN:
for(int i=0; i < windowsToUse.size(); i++)
{
HWND topChild = GetTopWindow(windowsToUse[i]);
PostMessage(topChild, WM_KEYDOWN, wParam, lParam);
}
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int iCmdShow)
{
std::vector<HWND> allWindows = getAllWindows();
addWindow(windowsToUse, allWindows, "Editor"); // Send to all windows that have "Editor" in their title
LPCTSTR className = L"MessageDistributor";
WNDCLASSEX wndClass = {0};
wndClass.cbSize = sizeof(WNDCLASSEX);
wndClass.lpfnWndProc = WindowProc;
wndClass.hInstance = hInst;
wndClass.lpszClassName = className;
if(!RegisterClassEx(&wndClass))
{
return 0;
}
HWND window = CreateWindowEx(WS_EX_APPWINDOW, className, L"Message Distributor", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 400, 400, 0, 0, hInst, 0);
if(window == 0)
{
int err = GetLastError();
return 0;
}
ShowWindow(window, true);
UpdateWindow(window);
MSG message;
while(GetMessage(&message, 0, 0, 0) > 0 )
{
TranslateMessage(&message);
DispatchMessage(&message);
}
return 0;
}
Ja der Code ist nicht der Schönste, aber das Prinzip sollte klar werden.
Kurze Erklärung:
Alle Fenster listen
Nach Titel filtern und die hinzufügen die du steuern willst (Hier nur notepad.exe aka Editor)
Top Child Window finden (Weil das Parent sie nicht immer an das Child weiterleitet)
Message an alle Fenster in unserer Liste weitersenden (nicht blockierend)
Die Handels kannst du natürlich auch anders finden.
Allerdings muss man dazu sagen, dass es eben nicht für alle Programme läuft. Je nachdem wie das Program den Input bekommt.