[erledigt] clipboardviewer Probleme
-
Hi,
Ich versuche ein Minimalprogram mit einem Clipboardviewer zu schreiben, aber ich bekomme keine Message.
SetClipboardViewer gibt 0 zuück, aber getLastError sagt 0, scheint also normal zu sein.Das ganze sollte nur ein Zwischenschritt sein.
Endziel ist es, das ganze in ein größeres Softwareprojekt einzubinden, wo ich prinzipiell auf gar kein Fenster oder WMD-Procs mehr Zugriff habe.
vom prinzip wär es mir also am liebsten, wenn das ganz ohne Fenster funktionieren würde und ich irgendwie eine Callback Routine registrieren könnte.Alternativ würde ich das versteckte Fenster aus einem Thread erzeugen.
Geht das überhaupt? Oder macht Windows da Probleme?// Modify the following defines if you have to target a platform prior to the ones specified below. // Refer to MSDN for the latest info on corresponding values for different platforms. #ifndef WINVER // Allow use of features specific to Windows XP or later. #define WINVER 0x0501 // Change this to the appropriate value to target other versions of Windows. #endif #ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later. #define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows. #endif #ifndef _WIN32_WINDOWS // Allow use of features specific to Windows 98 or later. #define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later. #endif #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers // MinWInApp.cpp : Defines the entry point for the application. // #include <windows.h> // C RunTime Header Files #include <stdlib.h> #include <malloc.h> #include <memory.h> #include <tchar.h> #include <strsafe.h> #define MAX_LOADSTRING 100 #define SZ_TITLE "MinWinApp" #define SZ_WND_CLASS "MINWINAPP" // Global Variables: HINSTANCE g_hInst; // current instance HWND g_hWnd; HWND g_hwndNextViewer; TCHAR* szWndClass = TEXT(SZ_WND_CLASS); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); // TODO: Place code here. MSG msg; WNDCLASSEX wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = NULL; wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1); wcex.lpszMenuName = NULL; wcex.lpszClassName = szWndClass; wcex.hIconSm = NULL; RegisterClassEx(&wcex); g_hInst = hInstance; // Store instance handle in our global variable g_hWnd = CreateWindow(szWndClass, TEXT(SZ_TITLE), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); if (!g_hWnd) { return FALSE; } ShowWindow(g_hWnd, SW_SHOW); // Main message loop: while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return (int) msg.wParam; } void ErrorExit(LPTSTR lpszFunction) { // Retrieve the system error message for the last-error code LPVOID lpMsgBuf; LPVOID lpDisplayBuf; DWORD dw = GetLastError(); if(!dw) // no error return; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL ); // Display the error message and exit the process lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, (lstrlen((LPCTSTR)lpMsgBuf)+lstrlen((LPCTSTR)lpszFunction)+40)*sizeof(TCHAR)); StringCchPrintf((LPTSTR)lpDisplayBuf, LocalSize(lpDisplayBuf) / sizeof(TCHAR), TEXT("%s failed with error %d: %s"), lpszFunction, dw, lpMsgBuf); MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK); LocalFree(lpMsgBuf); LocalFree(lpDisplayBuf); ExitProcess(dw); } LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { int wmId, wmEvent; switch (message) { case WM_CREATE: g_hwndNextViewer = SetClipboardViewer(g_hWnd); if(! g_hwndNextViewer) ErrorExit("setClipboardViewe"); break; case WM_CHANGECBCHAIN: // If the next window is closing, repair the chain. if ((HWND) wParam == g_hwndNextViewer) g_hwndNextViewer = (HWND) lParam; // Otherwise, pass the message to the next link. else if (g_hwndNextViewer != NULL) SendMessage(g_hwndNextViewer, message, wParam, lParam); break; case WM_DRAWCLIPBOARD: if( IsClipboardFormatAvailable(CF_TEXT) ) { if (OpenClipboard(hWnd)) { HGLOBAL hglb; LPSTR lpstr; hglb = GetClipboardData(CF_TEXT); lpstr = (LPSTR)GlobalLock(hglb); GlobalUnlock(hglb); CloseClipboard(); } } break; case WM_COMMAND: wmId = LOWORD(wParam); wmEvent = HIWORD(wParam); // Parse the menu selections: switch (wmId) { case 0: default: return DefWindowProc(hWnd, message, wParam, lParam); } break; case WM_DESTROY: ChangeClipboardChain(hWnd, g_hwndNextViewer); PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; }
-
Den Link kennst du schon, gibt da komplette Beispiele.
http://msdn.microsoft.com/en-us/library/ms649016
-
hmm, danke.
Das hat mir insofern geholfen, dass ich den Polling-Weg gefunden habe, der eher auf die eigentlich eProblemstellung passt.Wüsste trotzdem gerne, warum der Code nicht funktioniert.
Aber Teilweise hatte ich von der Seite schon geklaut.
-
[quote=\\"vlad_tepesch\\"]Wüsste trotzdem gerne, warum der Code nicht funktioniert[/quote] überleg dir mal ab wann g_hWnd gültig ist!
-
hWnd____ schrieb:
[quote=\\"vlad_tepesch\\"]Wüsste trotzdem gerne, warum der Code nicht funktioniert
überleg dir mal ab wann g_hWnd gültig ist![/quote]
*kopf gegen Wand schlag*
das rührte daher, dass ich das erst nach dem CreateWindow gemacht hatte, es dann aber ins WM_CREATE verschoben hatte, weil es so im Sample-Code stand und logischer aussah. hätte natürlich das g_ löschen müssen
jetzt gehts natürlich.
Danke