A simple breakdown of how it usually works.
When you create a parent window (hereinafter referred to as the "panel") containing the children, the flicker is usually caused by the window procedure of the parent window that processes the WM_ERASEBKGND message and draws "from above" all its children before instructing the children to redraw themselves.
, , CS_CLIPCHILDREN, , DefWindowProc(), ( ). , " ", , .
Windows . .
:
WM_MOUSEMOVE, WM_LBUTTONDOWN, WM_KEYDOWN ( ). Windows .
, , -, - ( ). WndProc() , , HWND.
. - .
RIGHT-CLICK , EDIT , ""!
#define _CRT_SECURE_NO_WARNINGS
#include <Windows.h>
#include <stdio.h>
LRESULT __stdcall WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
LRESULT __stdcall FrameProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
LRESULT __stdcall SubClassProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hpi, LPSTR lpcl, int ncs) {
WNDCLASSEX wcex;
MSG msg;
HWND hWnd=0, hFrame=0, hEdit=0, hButton=0, hCheckBox=0;
ATOM ca=0, caframe=0;
RECT cr;
HBRUSH framecolor;
int cx=0;
char *ptr=(char *)&wcex;
int i =0;
for (;i<sizeof(wcex);i++) {
ptr[i]=0;
}
wcex.cbSize=sizeof(wcex);
wcex.hbrBackground = (HBRUSH) COLOR_WINDOW;
wcex.hCursor = LoadCursor(0, IDC_ARROW);
wcex.lpfnWndProc = &WndProc;
wcex.lpszClassName = "mywnd";
wcex.hInstance = hInstance;
wcex.style = CS_HREDRAW|CS_VREDRAW;
ca = RegisterClassEx(&wcex);
for (i=0;i<sizeof(wcex);i++) {
ptr[i]=0;
}
wcex.cbSize=sizeof(wcex);
framecolor = CreateSolidBrush(0xFFA100);
wcex.hbrBackground = (HBRUSH) framecolor;
wcex.hCursor = LoadCursor(0, IDC_ARROW);
wcex.lpfnWndProc = &FrameProc;
wcex.lpszClassName = "myframe";
wcex.hInstance = hInstance;
wcex.style = CS_HREDRAW|CS_VREDRAW;
caframe = RegisterClassEx(&wcex);
hWnd = CreateWindowExA(0, (LPCSTR)ca, "My Window", WS_CLIPCHILDREN|WS_VISIBLE|WS_SYSMENU|WS_SIZEBOX, 100, 100, 500, 500, 0, 0, hInstance, 0);
GetClientRect(hWnd, &cr);
hFrame = CreateWindowExA(0, (LPCSTR)caframe, "", WS_VISIBLE|WS_BORDER|WS_CHILD|WS_CLIPCHILDREN, 10, 10, ((cr.right-cr.left)-20), ((cr.bottom-cr.top)-20), hWnd, (HMENU) 1, hInstance, 0);
cx = ((cr.right-cr.left)-20)/2;
hEdit = CreateWindowExA(0, "Edit", "Edit Control", WS_CHILD|WS_VISIBLE|WS_BORDER, 10, 10, cx, 20, hFrame, (HMENU) 2, hInstance, 0);
hButton = CreateWindowExA(0, "Button", "Click Me!", WS_CHILD|WS_VISIBLE, cx+20, 10, 70, 20, hFrame, (HMENU) 3, hInstance, 0);
SetWindowLongPtr(hEdit, GWLP_USERDATA, GetWindowLongPtr(hEdit, GWLP_WNDPROC));
SetWindowLongPtr(hButton, GWLP_USERDATA, GetWindowLongPtr(hButton, GWLP_WNDPROC));
SetWindowLongPtr(hEdit, GWLP_WNDPROC, (LONG)&SubClassProc);
SetWindowLongPtr(hButton, GWLP_WNDPROC, (LONG)&SubClassProc);
if (!hWnd) {
return -1;
}
while ( GetMessage(&msg, 0, 0, 0) ) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
DestroyWindow(hWnd);
DeleteObject(framecolor);
return 0;
}
LRESULT __stdcall WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) {
RECT rc;
switch (uMsg) {
case WM_WINDOWPOSCHANGING:
GetClientRect(hWnd, &rc);
SetWindowPos(GetDlgItem(hWnd, 1), 0, 0, 0, ((rc.right-rc.left)-20), ((rc.bottom-rc.top)-20), SWP_NOZORDER|SWP_NOMOVE);
break;
case WM_CLOSE:
PostQuitMessage(0);
break;
default:
break;
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
LRESULT __stdcall FrameProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) {
PAINTSTRUCT ps;
WINDOWPOS *wp=0;
POINT p;
short wmid=0, wmevent=0;
char message[300];
switch (uMsg) {
case WM_WINDOWPOSCHANGING:
wp = (WINDOWPOS *)lParam;
SetWindowPos(GetDlgItem(hWnd, 2), 0, 0, 0, (wp->cx/2), 20, SWP_NOMOVE|SWP_NOZORDER);
SetWindowPos(GetDlgItem(hWnd, 3), 0, (wp->cx/2)+20, 10, 0, 0, SWP_NOSIZE|SWP_NOZORDER);
break;
case WM_RBUTTONDOWN:
p.x = (lParam & 0x0000ffff);
p.y = (lParam >> 16 );
sprintf(message, "The \"frame\" got a WM_RBUTTONDOWN message!\nx: %i\ny: %i\n",
p.x, p.y);
MessageBox(GetParent(hWnd), message, "Message", MB_ICONINFORMATION);
break;
case WM_COMMAND:
wmid = (wParam & 0x0000ffff);
wmevent = wParam>>16;
switch (wmid) {
case 3:
if (wmevent==BN_CLICKED) {
MessageBox(GetParent(hWnd), "You clicked my button!", "Notice", MB_OK);
}
break;
default:
break;
}
break;
case WM_PAINT:
break;
default:
break;
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
LRESULT __stdcall SubClassProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) {
WNDPROC wp=0;
POINT p;
HWND hParent=0;
char message[300];
wp = (WNDPROC)GetWindowLongPtr(hWnd, GWLP_USERDATA);
if (!wp) {
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
if (uMsg==WM_RBUTTONDOWN) {
p.x = (lParam & 0x0000ffff);
p.y = (lParam >> 16 );
sprintf(message, "Right-Click in control!\nx: %i\ny: %i\n\nNow, we'll convert this to the coordinates of the frame and pass the message up-stream!",
p.x, p.y);
hParent = GetParent(hWnd);
MessageBox(GetParent(hParent), message, "Message", MB_ICONINFORMATION);
ClientToScreen(hWnd, &p);
ScreenToClient(hParent, &p);
SendMessage(hParent, WM_RBUTTONDOWN, wParam, MAKELPARAM(p.x, p.y));
}
return CallWindowProc( wp, hWnd, uMsg, wParam, lParam);
}
Windows WM_COMMAND WM_NOTIFY. , . WM_COMMAND ,
A.
B.
C. (), EN_CHANGE.
, SendMessage() , .
, :
- .
- WM_PAINT.
- , WM_PRINTCLIENT.
- BitBlt()
- , .
. bkausbk, . , , , BitBlt() WM_PAINT ( ), , .
PAINTSTRUCT ps;
case WM_PAINT:
BeginPaint(hWnd, &ps);
BitBlt(ps.hdc, 0, 0, cx, cy, hMemDC, 0, 0, SRCCOPY);
EndPaint(hWnd &ps);
, , , , !