我在Visual Studio 2010中创build了一个标准的win32 windows应用程序。我唯一添加的是WM_PAINT处理程序中的一个TextOut调用,它在位置0,0处显示字母(宽度重复4次)。
我的问题是,当我调整窗口的大小,扩大到右边,右边框有一些绘图错误。 在resize/绘图过程中会显示黑块,就好像右手边被拉伸一样。 当我resize时,结果是一个奇怪的黑色“拖尾”效果。 它只发生在resize; 一旦我释放鼠标,窗口看起来是正确的。
我曾尝试双缓冲到内存DC,但看到相同的效果。 我没有使用任何Windows主题代码。
我可以删除效果的唯一方法是处理WM_NCPAINT(并返回0) – 但是,当然,这意味着边框不会被绘制,这不会是一个可以接受的解决scheme! 我提到它可以帮助任何有想法的人。
@Arx – 对不起,我没有明确表示。 当我说边框拖影,我的意思是显示的文字的右手边缘,而不是边框本身。
如果我只是在WM_PAINT处理程序中添加TextOut调用,就会发生这种情况。 处理WM_ERASEBKGRND和设置窗口类背景画笔没有区别。
@大卫 – 道歉。 在添加一行到由新项目向导创build的标准VS 2008 Win32应用程序之后,我看到了这种效果 – 所以我没有看到只发现一行代码的200多行代码的意思:)
我将这一行添加到WM_PAINT处理程序:
TextOut (hdc, 0, 0, L"ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ", 104);
下面是添加了双缓冲的代码的完整版本。 当窗口展开时,右侧(窗口边缘)的文字涂抹仍然存在。
// win32_smearing_at_border.cpp : Defines the entry point for the application. // #include "stdafx.h" #include "win32_smearing_at_border.h" #define MAX_LOADSTRING 100 // Global Variables: HINSTANCE hInst; // current instance TCHAR szTitle[MAX_LOADSTRING]; // The title bar text TCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name // Forward declarations of functions included in this code module: ATOM MyRegisterClass(HINSTANCE hInstance); BOOL InitInstance(HINSTANCE, int); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); INT_PTR CALLBACK About(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; HACCEL hAccelTable; // Initialize global strings LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); LoadString(hInstance, IDC_WIN32_SMEARING_AT_BORDER, szWindowClass, MAX_LOADSTRING); MyRegisterClass(hInstance); // Perform application initialization: if (!InitInstance (hInstance, nCmdShow)) { return FALSE; } hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WIN32_SMEARING_AT_BORDER)); // Main message loop: while (GetMessage(&msg, NULL, 0, 0)) { if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } } return (int) msg.wParam; } // // FUNCTION: MyRegisterClass() // // PURPOSE: Registers the window class. // // COMMENTS: // // This function and its usage are only necessary if you want this code // to be compatible with Win32 systems prior to the 'RegisterClassEx' // function that was added to Windows 95. It is important to call this function // so that the application will get 'well formed' small icons associated // with it. // ATOM MyRegisterClass(HINSTANCE hInstance) { 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 = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WIN32_SMEARING_AT_BORDER)); wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = 0; //(HBRUSH)(COLOR_WINDOW+1); wcex.lpszMenuName = MAKEINTRESOURCE(IDC_WIN32_SMEARING_AT_BORDER); wcex.lpszClassName = szWindowClass; wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); return RegisterClassEx(&wcex); } // // FUNCTION: InitInstance(HINSTANCE, int) // // PURPOSE: Saves instance handle and creates main window // // COMMENTS: // // In this function, we save the instance handle in a global variable and // create and display the main program window. // BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) { HWND hWnd; hInst = hInstance; // Store instance handle in our global variable hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); if (!hWnd) { return FALSE; } ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); return TRUE; } // // FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM) // // PURPOSE: Processes messages for the main window. // // WM_COMMAND - process the application menu // WM_PAINT - Paint the main window // WM_DESTROY - post a quit message and return // // LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { int wmId, wmEvent; PAINTSTRUCT ps; HDC hdc; static HDC memory_dc; static HBITMAP memory_bmp; static HBITMAP oldbmp; switch (message) { case WM_COMMAND: wmId = LOWORD(wParam); wmEvent = HIWORD(wParam); // Parse the menu selections: switch (wmId) { case IDM_ABOUT: DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About); break; case IDM_EXIT: DestroyWindow(hWnd); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } break; case WM_ERASEBKGND: return 1; case WM_CREATE: // Create memory DC { HDC dc = GetDC (hWnd); memory_dc = CreateCompatibleDC (dc); memory_bmp = CreateCompatibleBitmap (dc, 2560, 1440); // arbitary values for testing, set to my current monitor size. oldbmp = (HBITMAP)SelectObject(memory_dc, memory_bmp); TextOut (memory_dc, 0, 0, L"ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ",104); ReleaseDC (hWnd, dc); } case WM_PAINT: hdc = BeginPaint(hWnd, &ps); BitBlt(hdc, ps.rcPaint.left, ps.rcPaint.top, ps.rcPaint.right-ps.rcPaint.left, ps.rcPaint.bottom-ps.rcPaint.top, memory_dc, ps.rcPaint.left, ps.rcPaint.top, SRCCOPY); EndPaint(hWnd, &ps); break; case WM_DESTROY: // Clean up memory DC SelectObject (memory_dc,oldbmp); DeleteObject (memory_bmp); DeleteDC (memory_dc); PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; } // Message handler for about box. INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { UNREFERENCED_PARAMETER(lParam); switch (message) { case WM_INITDIALOG: return (INT_PTR)TRUE; case WM_COMMAND: if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) { EndDialog(hDlg, LOWORD(wParam)); return (INT_PTR)TRUE; } break; } return (INT_PTR)FALSE; }
嗨Arx
非常感谢您尝试代码 – 我很感激。 很高兴知道这是为你工作。
但是…我正在经历一些非常奇怪的结果。 在Windows 7 x64机器上运行时遇到“模糊”问题。 但是,在Windows 7虚拟机(在同一台机器上使用VMWare)试用它,它可以很好地工作。
所以在同一台机器上,它本身就模糊了,但实际上并没有。 我什至尝试了一个Windows 8的虚拟机,并再次工作正常。
我发现的是,如果我select一个非航空主题,所有工作都可以(虽然没有Aero的话它看起来不那么好)。 然而,在其他机器上,它们确实select了Aero主题。 我真的不明白。
所以这不是一个真正的解决scheme。 我不想问我的潜在客户closuresAero。
我试图调用许多Dwm *函数来试图找出工作和非工作机器之间的区别,但是找不到任何东西。
如果我插入这个代码:
DWMNCRENDERINGPOLICY policy = DWMNCRP_DISABLED; DwmSetWindowAttribute(hWnd, DWMWA_NCRENDERING_POLICY, (void*)&policy, sizeof(DWMNCRENDERINGPOLICY));
创build主窗口后,所有工作再次正常(虽然,再次,没有航空边界看起来不错)。
所以我真的不知如何往前走。 任何想法感激地收到!