1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
|
// Main.cpp
#include <stdio.h>
#include <windows.h>
#define BTSWAP 9001 // Id for Swap button.
// create structure that holds a name & age.
struct Person { LPCSTR lpszName; int iAge; };
LRESULT CALLBACK WinProc(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam)
{
switch (Msg) // handle messages.
{
case WM_CREATE:
{ /* this message is trapped before the window appears. */
Person*ptrPerson=new Person[2]; // allocate memory for two objects of type person.
if(ptrPerson) // if the memory was allocated...
{ // fill in object parameters; name & age.
ptrPerson[0].lpszName="Billy"; ptrPerson[0].iAge=26; // billy likes a girl.
ptrPerson[1].lpszName="Sarah"; ptrPerson[1].iAge=19; // her name is sarah.
} else return -1;// if memory allocation fails, abort! sarah hates billy.
// note that I did not create a null pointer.
SetWindowLongPtr(hWnd,0,(long)ptrPerson); // store pointer address in wnd extra bytes.
/* the Swap button is part of the window so, we should create it here. */
HWND hBtSwap=CreateWindow
("button", // pre-defined button class
"Swap", // the text in our button
WS_CHILD|BS_PUSHBUTTON, // the relationship & button type
100,20, // horizontal & vertical position
100,80, // width & height of the button
hWnd, // parent of the button
(HMENU)BTSWAP, // the button Id, how we find it.
GetModuleHandle(NULL), // application instance handle.
NULL); // no window creation-data.
ShowWindow(hBtSwap,SW_SHOW); // display Swap button.
/* I allocated 8 bytes, that means I have two offsets I can access to store information
with SetWindowLongPtr() the first is at offset 0 and the second is at offset 4, each
offset is 4 bytes. We will store the address of the button handle at offset 4. */
SetWindowLongPtr(hWnd,4,(long)hBtSwap); // whoat wait, was hBtSwap a pointer!?
/* yes, a HWND is actually a pointer! so hBtSwap is a pointer to the button. */
break;
}
case WM_PAINT:
{
char chBuffer[128]; // temporary character buffer
PAINTSTRUCT ps; // paint structure
HDC WinDC; // device-context handle
WinDC=BeginPaint(hWnd,&ps); // begin paint scene in device-context
// create and fetch pointer from wnd extra bytes
Person*ptrPerson=(Person*)GetWindowLongPtr(hWnd,0);
/* now we will output data with the pointer. I use sprintf() from <stdio.h> */
TextOut(WinDC,10,10,ptrPerson[0].lpszName,strlen(ptrPerson[0].lpszName)); // billy
sprintf(chBuffer,"Age: %i",ptrPerson[0].iAge); // format string with billy's age.
TextOut(WinDC,10,30,chBuffer,strlen(chBuffer)); // display the formated string.
TextOut(WinDC,10,70,ptrPerson[1].lpszName,strlen(ptrPerson[1].lpszName)); // sarah
sprintf(chBuffer,"Age: %i",ptrPerson[1].iAge); // format string with sarah's age.
TextOut(WinDC,10,90,chBuffer,strlen(chBuffer)); // display the formated string.
/* tell the user what the Swap button does. */
sprintf(chBuffer,"Click Swap button to swap Billy & Sarah data.");
TextOut(WinDC,10,130,chBuffer,strlen(chBuffer));
/* some more information for the user. */
sprintf(chBuffer,"Press Delete to hide Swap button, Insert to show.");
TextOut(WinDC,10,150,chBuffer,strlen(chBuffer));
EndPaint(hWnd,&ps); // end paint scene, releases device-context.
break;
}
case WM_COMMAND:
{
if(LOWORD(wParam)==BTSWAP) // Is it the swap button?
{ /* swap the contents of the objects. */
LPCSTR lpszName; // temp; to store name
int iAge; // temp; to store age
// create & fetch pointer from wnd extra bytes
Person*ptrPerson=(Person*)GetWindowLongPtr(hWnd,0);
// move data from object in position 0 to temporary variables
lpszName=ptrPerson[0].lpszName;
iAge=ptrPerson[0].iAge;
// now move object in position 1 to position 0
ptrPerson[0].lpszName=ptrPerson[1].lpszName;
ptrPerson[0].iAge=ptrPerson[1].iAge;
// now move data in temporary variables to position 1
ptrPerson[1].lpszName=lpszName;
ptrPerson[1].iAge=iAge;
/* the swap is complete. */
InvalidateRect(hWnd,NULL,true); // update the window.
SetFocus(hWnd); // give focus back to the window.
/* I give focus back to the window because when the button is pressed, it
stays selected (focused) and the delete & insert keys wont work to hide
and show the button, we want those to work for this application. */
}
break;
}
case WM_KEYDOWN:
{ /* handle virtual key messages only. */
if (wParam==VK_DELETE) // delete is pressed, hide the button.
{ // create handle & fetch pointer from wnd extra bytes.
HWND hBtSwap=(HWND)GetWindowLongPtr(hWnd,4);
// I did not use (HWND*) this time because HWND is already a pointer!
ShowWindow(hBtSwap,SW_HIDE); // hides the button.
}
if (wParam==VK_INSERT) // insert is pressed, show the button.
{ // create handle & fetch pointer from wnd extra bytes.
HWND hBtSwap=(HWND)GetWindowLongPtr(hWnd,4);
// I did not use (HWND*) this time because HWND is already a pointer!
ShowWindow(hBtSwap,SW_SHOW); // shows the button.
}
break;
}
case WM_DESTROY:
{ /* terminate the application. */
// create and fetch pointer from wnd extra bytes.
Person*ptrPerson=(Person*)GetWindowLongPtr(hWnd,0);
delete [] ptrPerson; // free up the allocated memory.
PostQuitMessage(0); // post quit message and get out.
break;
}
default:
/* pass non-trapped messages to DefWindowProc */
return DefWindowProc(hWnd,Msg,wParam,lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hIns,HINSTANCE hPrev,char*pArgs,int iShow)
{
MSG Msg;
HWND hWnd;
WNDCLASSEX WinClassEx;
WinClassEx.hInstance=hIns;
WinClassEx.lpszClassName="WindowClassEx";
WinClassEx.lpfnWndProc=WinProc;
WinClassEx.style=CS_HREDRAW|CS_VREDRAW;
WinClassEx.hIcon=LoadIcon(NULL,IDI_APPLICATION);
WinClassEx.hIconSm=LoadIcon(NULL,IDI_APPLICATION);
WinClassEx.hCursor=LoadCursor(NULL,IDC_ARROW);
WinClassEx.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
WinClassEx.lpszMenuName=NULL;
WinClassEx.cbClsExtra=0;
WinClassEx.cbWndExtra=8; // window extra bytes
WinClassEx.cbSize=sizeof(WNDCLASSEX);
RegisterClassEx(&WinClassEx);
int iWidth=500; int iHeight=200;
RECT DesktopRect; SystemParametersInfo(SPI_GETWORKAREA, 0, &DesktopRect, 0);
int iWindowX=(DesktopRect.right-iWidth)/2;
int iWindowY=(DesktopRect.bottom-iHeight)/2;
hWnd = CreateWindowEx(0,
WinClassEx.lpszClassName,
"Billy&Sarah",
WS_OVERLAPPEDWINDOW &~WS_SIZEBOX&~WS_MINIMIZEBOX&~WS_MAXIMIZEBOX,
iWindowX, iWindowY,
iWidth, iHeight,
HWND_DESKTOP,
NULL,
WinClassEx.hInstance,
NULL);
ShowWindow(hWnd,SW_SHOWNORMAL);
while(GetMessage(&Msg,NULL,0,0) > 0)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}
|