#include <windows.h> #define DIVISIONS 5 LRESULT CALLBACK MainWndProc(HWND,UINT,WPARAM,LPARAM); LRESULT CALLBACK ChildWndProc(HWND,UINT,WPARAM,LPARAM); TCHAR szChildName[]=TEXT("ChildWindow"); int idFocus=0; int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPreInstance,LPSTR lpCmdLine,int nShowCmd) { static TCHAR szAppName[]=TEXT("MainWindow"); HWND hwnd; MSG msg; WNDCLASS wndcls; wndcls.cbClsExtra=0; wndcls.cbWndExtra=0; wndcls.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH); wndcls.hCursor=LoadCursor(NULL,IDC_ARROW); wndcls.hIcon=LoadIcon(NULL,IDI_APPLICATION); wndcls.hInstance=hInstance; wndcls.lpfnWndProc=MainWndProc; wndcls.lpszClassName=szAppName; wndcls.lpszMenuName=NULL; wndcls.style=CS_HREDRAW | CS_VREDRAW; if(!RegisterClass(&wndcls)) { MessageBox(NULL,TEXT("You Need Windows NT"),szAppName,MB_ICONERROR); return 0; } wndcls.cbWndExtra=sizeof(long); wndcls.hIcon=NULL; wndcls.lpfnWndProc=ChildWndProc; wndcls.lpszClassName=szChildName; wndcls.style|=CS_DBLCLKS; RegisterClass(&wndcls); hwnd=CreateWindow(szAppName,TEXT("Child Window Demo"), WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT, CW_USEDEFAULT,NULL,NULL,hInstance,NULL); ShowWindow(hwnd,nShowCmd); UpdateWindow(hwnd); while(GetMessage(&msg,NULL,0,0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } LRESULT CALLBACK MainWndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam) { static HWND hwndChild[DIVISIONS][DIVISIONS]; int cxBlock,cyBlock,x,y; switch(message) { case WM_CREATE: for(x=0;x<DIVISIONS;x++) for(y=0;y<DIVISIONS;y++) hwndChild[x][y]=CreateWindow(szChildName,NULL,WS_CHILD | WS_VISIBLE /*|WS_THICKFRAME*/,0,0,0,0, hwnd,(HMENU)(y<<8|x),(HINSTANCE)GetWindowLong(hwnd,GWL_HINSTANCE),NULL); //hMenu在创建子窗口时表示子窗口ID return 0; case WM_SIZE: cxBlock=LOWORD(lParam)/DIVISIONS; cyBlock=HIWORD(lParam)/DIVISIONS; for(x=0;x<DIVISIONS;x++) for(y=0;y<DIVISIONS;y++) MoveWindow(hwndChild[x][y],x*cxBlock,y*cyBlock,cxBlock,cyBlock,TRUE); return 0; case WM_SETFOCUS: SetFocus(GetDlgItem(hwnd,idFocus)); return 0; case WM_KEYDOWN: x=idFocus & 0xFF; y=idFocus>>8; switch(wParam) { case VK_UP: y--; break; case VK_DOWN: y++; break; case VK_LEFT: x--; break; case VK_RIGHT: x++; break; default: return 0; } x=(x+DIVISIONS)%DIVISIONS; y=(y+DIVISIONS)%DIVISIONS; SetFocus(hwndChild[x][y]); return 0; case WM_DESTROY: PostQuitMessage(0); return 0; } return DefWindowProc(hwnd,message,wParam,lParam); } LRESULT CALLBACK ChildWndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam) { HDC hdc; PAINTSTRUCT ps; RECT rect={(0,0,0,0)}; switch(message) { case WM_CREATE: SetWindowLong(hwnd,0,0); return 0; case WM_LBUTTONDOWN: SetFocus(hwnd); return 0; case WM_LBUTTONDBLCLK: SetWindowLong(hwnd,0,1^GetWindowLong(hwnd,0)); InvalidateRect(hwnd,NULL,FALSE); return 0; case WM_SETFOCUS: idFocus=GetWindowLong(hwnd,GWL_ID); InvalidateRect(hwnd,NULL,FALSE); return 0; case WM_KILLFOCUS: InvalidateRect(hwnd,NULL,FALSE); return 0; case WM_KEYDOWN: if(wParam==VK_SPACE || wParam==VK_RETURN) SendMessage(hwnd,WM_LBUTTONDBLCLK,0,0); else SendMessage(GetParent(hwnd),message,wParam,lParam); return 0; case WM_PAINT: hdc=BeginPaint(hwnd,&ps); GetClientRect(hwnd,&rect); if(hwnd==GetFocus()) { SelectObject(hdc,CreatePen(PS_SOLID,5,RGB(0,0,255))); Rectangle(hdc,rect.left,rect.top,rect.right,rect.bottom); DeleteObject(SelectObject(hdc,GetStockObject(BLACK_PEN))); } else Rectangle(hdc,rect.left,rect.top,rect.right,rect.bottom); if(GetWindowLong(hwnd,0)) { MoveToEx(hdc,0,0,NULL); LineTo(hdc,rect.right,rect.bottom); MoveToEx(hdc,rect.right,0,NULL); LineTo(hdc,0,rect.bottom); } EndPaint(hwnd,&ps); return 0; } return DefWindowProc(hwnd,message,wParam,lParam); }