|
-
May 23rd, 2004, 11:31 AM
#1
Switching focus from child window to child window
I just finished this program and one thing that was bothering me was a few nitpick things that made it work, I'm not sure how, maybe I'm just not looking at the problem correctly.
Code:
#include <windows.h>
#define DIVISIONS 5
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK ChildWndProc(HWND, UINT, WPARAM, LPARAM);
int idFocus = 0;
TCHAR szChildClass[] = TEXT("Checker4_Child");
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT("Checker4");
HWND hwnd;
MSG msg;
WNDCLASS wndclass;
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szAppName;
if(!RegisterClass(&wndclass))
{
MessageBox(NULL, TEXT("This program requires a Windows OS that supports Unicode."),
szAppName, MB_ICONERROR);
return 0;
}
wndclass.lpfnWndProc = ChildWndProc;
wndclass.cbWndExtra = sizeof(long);
wndclass.hIcon = NULL;
wndclass.lpszClassName = szChildClass;
if(!RegisterClass(&wndclass))
{
MessageBox(NULL, TEXT("An error has occured while attempting to register a child window."),
szAppName, MB_ICONERROR);
return 0;
}
hwnd = CreateWindow(szAppName, TEXT("Checker4 Mouse Hit-Test Demo"), WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
ShowWindow(hwnd, iCmdShow);
UpdateWindow(hwnd);
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
// handles all of the little child windows together, however, does not control the user input
// to each child window
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
// window handles for 25 child windows
static HWND hwndChild[DIVISIONS][DIVISIONS];
// none of the below values are static because they need to be used once whenever the
// WM_SIZE message is processed, they are not used whenever any other message is processed
// will hold the length of the client area
int cxBlock;
// will hold the height of the client area
int cyBlock;
// the below 2 values are mostly for loop iterations and keeping track of the focus box
// will hold the length of the child window
int x;
// will hold the height of the child window
int y;
switch(message)
{
case WM_CREATE:
for(x = 0; x < DIVISIONS; x++)
{
for(y = 0; y < DIVISIONS; y++)
{
// create 25 child windows
hwndChild[x][y] = CreateWindow(szChildClass, NULL, WS_CHILDWINDOW | WS_VISIBLE,
0, 0, 0, 0, hwnd, (HMENU)(y << 8 | x),
// get the instance from the parent window using this method with these
// values passed into it
(HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE),
NULL);
}
}
return 0;
case WM_SIZE:
// get the size of the entire client area in the parent window and divide it by 5,
// this will tell the average height and length of the child windows
cxBlock = LOWORD(lParam) / DIVISIONS;
cyBlock = HIWORD(lParam) / DIVISIONS;
for(x = 0; x < DIVISIONS; x++)
{
for(y = 0; y < DIVISIONS; y++)
{
// realign the child windows so that they would all fit within the client area
// of the parent window
MoveWindow(hwndChild[x][y], x * cxBlock, y * cyBlock, cxBlock, cyBlock, TRUE);
}
}
return 0;
// if the left-mouse-button is pressed somewhere in the main window, a error message beep
// will be given
case WM_LBUTTONDOWN:
MessageBeep(0);
return 0;
// On set-focus message, set focus to child window
case WM_SETFOCUS:
// get the focus from one child window to another
SetFocus(GetDlgItem(hwnd, idFocus));
return 0;
// On key-down message, possible change the focus window
case WM_KEYDOWN:
x = idFocus & 0xFF;
y = idFocus >> 8;
switch(wParam)
{
// move the focus square up
case VK_UP:
y--;
break;
// move the focus square down
case VK_DOWN:
y++;
break;
// move the focus square left
case VK_LEFT:
x--;
break;
// move the focus square right
case VK_RIGHT:
x++;
break;
// move the focus square all the way to the top and to the left
case VK_HOME:
x = 0;
y = 0;
break;
// move the focus square all the way to the bottom and to the right
case VK_END:
x = DIVISIONS - 1;
y = DIVISIONS - 1;
break;
default:
break;
}
// calculate the position where the
x = (x + DIVISIONS) % DIVISIONS;
y = (y + DIVISIONS) % DIVISIONS;
// move everything over by eight bits and add to itthe variable x
idFocus = y << 8 | x;
// set the focus to another child window from a previous one
SetFocus(GetDlgItem(hwnd, idFocus));
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;
switch(message)
{
// passes into the reserved memory a 0, indicating that an X is not to be drawn in a
// particular window
case WM_CREATE:
SetWindowLong(hwnd, 0, 0); // on/off flag
return 0;
case WM_KEYDOWN:
// send most key presses to the parent window
if(wParam != VK_RETURN && wParam != VK_SPACE)
{
// first value passed into the function is the window handle to the parent window
SendMessage(GetParent(hwnd), message, wParam, lParam);
return 0;
}
// for return and space fall through to toggle the square
case WM_RBUTTONDOWN:
case WM_LBUTTONDOWN:
// resets the the special value that is being stored
// in this case the value is xored with a 1 and if the original value was 0(no X is
// there from the outstart), the new value would be a 1
// however, if the previous value was a 1 then a xor with another 1 would yield a 0
// and the whole X would be erased across the child window
SetWindowLong(hwnd, 0, 1 ^ GetWindowLong(hwnd, 0));
// sets the focus to this particular child window
SetFocus(hwnd);
// the entire window will be redrawn
InvalidateRect(hwnd, NULL, FALSE);
return 0;
// for focus messages, invalidate the window for repaint
case WM_SETFOCUS:
// get the id of the particular child window
idFocus = GetWindowLong(hwnd, GWL_ID);
// fall through
case WM_KILLFOCUS:
InvalidateRect(hwnd, NULL, TRUE);
return 0;
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
GetClientRect(hwnd, &rect);
Rectangle(hdc, 0, 0, rect.right, rect.bottom);
// draw the X
if(GetWindowLong(hwnd, 0))
{
MoveToEx(hdc, 0, 0, NULL);
LineTo(hdc, rect.right, rect.bottom);
MoveToEx(hdc, 0, rect.bottom, NULL);
LineTo(hdc, rect.right, 0);
}
// draw the focus rectangle
if(hwnd == GetFocus())
{
rect.left += rect.right / 10;
rect.right -= rect.left;
rect.top += rect.bottom / 10;
rect.bottom -= rect.top;
// inbetween the dashes there will be nothing drawn
SelectObject(hdc, GetStockObject(NULL_BRUSH));
// a dashed line will outline a rectangle
SelectObject(hdc, CreatePen(PS_DASH, 0, 0));
Rectangle(hdc, rect.left, rect.top, rect.right, rect.bottom);
DeleteObject(SelectObject(hdc, GetStockObject(BLACK_PEN)));
}
EndPaint(hwnd, &ps);
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
My question is about the 2 different portions that I made bold.
---------------------------------------------------------------------------------
The first one. Since idFocus is initially 0. In the first line of the first bold portion, the entire thing is anded with a 0xFF. Why would one do that? I guess what I'm asking for is a nuts and bolts explanation.
Then in the first part on the second line, 8 bits are moved over to the right. Again why would you do that(in the context to the entire program)?
-------------------------------------------------------------------------------
On the second boldened part, 8 bits in y are moved to the left and then it uses or with x and re-assigns it to idFocus. Why?
----------------------------------------------------------------------------------
Thanks in advance for your comments, I'll keep at this problem for some time.
Favorite music:
Rammstein
E nomine
Prodigy
"Beer, the solution and the cause of all of our problems" -- Homer Simpson
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|