First off if you are reading this tutorial, I am going to assume a few things. Because windows programming is "more advanced" than console programming I am going to have to assume you have a good grasp on C/C++. You need to know what #include's are and how to use them, you need to know how to use arrays and pointers, you need to know how to use switch() and case's, and you need to know what a typedef is. These are things this tutorial will not cover. I will format my code to my style, this to make it easier for me and you to read.
You are also going to need a C/C++ Compiler that supports Windows API. I used Borlands Free C/C++ 5.5 Compiler to compile all of these examples, basically because I am to cheap to get Microsoft Visual C++ and Borland is free alternative. For information on getting a free compiler see the Tools Appendix. For information on how to compile windows programs with the compiler see the Compiler Section.
I like to look at the code and compiled examples before I go over what it all means so after each example I will go over the code to clarify what it means.
1.2 Simple Message
#include <windows.h> int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { MessageBox (NULL, "Hello World" , "Hello", 0); return 0; } |
Put that code in a test file and compile it, any errors you get consult your
compilers help files. Now lets go through the code.
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
WinMain() is the windows equivalent of main() in DOS and UNIX. This is where the
program starts. WinMain() takes the following parameters:
#include <windows.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); static char gszClassName[] = "MyWindowClass"; static HINSTANCE ghInstance = NULL; int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { WNDCLASSEX WndClass; HWND hwnd; MSG Msg; ghInstance = hInstance; WndClass.cbSize = sizeof(WNDCLASSEX); WndClass.style = NULL; WndClass.lpfnWndProc = WndProc; WndClass.cbClsExtra = 0; WndClass.cbWndExtra = 0; WndClass.hInstance = ghInstance; WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION); WndClass.hCursor = LoadCursor(NULL, IDC_ARROW); WndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); WndClass.lpszMenuName = NULL; WndClass.lpszClassName = gszClassName; WndClass.hIconSm = LoadIcon(NULL, IDI_APPLICATION); if(!RegisterClassEx(&WndClass)) { MessageBox(0, "Window Registration Failed!", "Error!", MB_ICONSTOP | MB_OK); return 0; } hwnd = CreateWindowEx( WS_EX_STATICEDGE, gszClassName, "Windows Title", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 320, 240, NULL, NULL, ghInstance, NULL); if(hwnd == NULL) { MessageBox(0, "Window Creation Failed!", "Error!", MB_ICONSTOP | MB_OK); return 0; } ShowWindow(hwnd, nCmdShow); UpdateWindow(hwnd); while(GetMessage(&Msg, NULL, 0, 0)) { TranslateMessage(&Msg); DispatchMessage(&Msg); } return Msg.wParam; } LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) { switch(Message) { case WM_CLOSE: DestroyWindow(hwnd); break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hwnd, Message, wParam, lParam); } return 0; } |
As you can see its a good 70 or so lines to make a simple window.
Windows Programs unlike DOS or UNIX programs are event driven. Windows programs
generaly stay idle untill they recive a message, they act on that message, and then
wait for the next one. When a windows program does respond to a message its called
handling the message.
As you see I decalred my WiinProc function so that it can be used later on. I decalerd
my variables (I prfer to use Hungarian Notation, but you can use what you want).
Inside the function WiNmain() we see some new variables. These are WndClass, hwnd,
and msg. The WndClass is the structure that holds all of the widnows class information
which is later passed to RegisterClassEx(). The hwnd structure identifies the window.
The msg structure contains message information from a thread's message queue. The
next thing we come to is when the hInstance is made global in the variable ghInstance.
After that we come to the defining of each of the WndClass settings:
Now most windows programmers (including myself) never memorize much of that. We
usually take a simple window application like that and use it as a skelaton for
all of our new applications, adding what we need and changning things. This is what
I am going to do throughout the entire tutorial. I will take this code form the
last section and I will reuse it in all outher applications that have a window.
Now next up how do we write text to our window? This to is not as simple as it may
seem.
#include <windows.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); static char gszClassName[] = "MyWindowClass"; static HINSTANCE ghInstance = NULL; int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { WNDCLASSEX WndClass; HWND hwnd; MSG Msg; ghInstance = hInstance; WndClass.cbSize = sizeof(WNDCLASSEX); WndClass.style = NULL; WndClass.lpfnWndProc = WndProc; WndClass.cbClsExtra = 0; WndClass.cbWndExtra = 0; WndClass.hInstance = ghInstance; WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION); WndClass.hCursor = LoadCursor(NULL, IDC_ARROW); WndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); WndClass.lpszMenuName = NULL; WndClass.lpszClassName = gszClassName; WndClass.hIconSm = LoadIcon(NULL, IDI_APPLICATION); if(!RegisterClassEx(&WndClass)) { MessageBox(0, "Window Registration Failed!", "Error!", MB_ICONSTOP | MB_OK); return 0; } hwnd = CreateWindowEx( WS_EX_STATICEDGE, gszClassName, "Windows Title", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 320, 240, NULL, NULL, ghInstance, NULL); if(hwnd == NULL) { MessageBox(0, "Window Creation Failed!", "Error!", MB_ICONSTOP | MB_OK); return 0; } ShowWindow(hwnd, nCmdShow); UpdateWindow(hwnd); while(GetMessage(&Msg, NULL, 0, 0)) { TranslateMessage(&Msg); DispatchMessage(&Msg); } return Msg.wParam; } LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) { HDC hdc; PAINTSTRUCT ps; LPSTR szMessage = "Hello World"; switch(Message) { case WM_PAINT: hdc = BeginPaint(hwnd, &ps); TextOut(hdc, 70, 50, szMessage, strlen(szMessage)); EndPaint(hwnd, &ps); break; case WM_CLOSE: DestroyWindow(hwnd); break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hwnd, Message, wParam, lParam); } return 0; } |
When programming there are usually a few ways to do things, making a windows menu is no different. I am going to go over the two main ways you can make a menu. I will have each one make the same menu but it will show you different ways of doing things.
1.5.1 ResourcesResources is probably the simplest way of making a menu. The menu is predefined
in a resource file (always something.rc). The resource files are compiled by the
resource compiler and linked to the program when the linker runs. This is the first
program where I am also going to throw other files besides the source files in.
There will be a resource file (*.rc) and a header file (*.h) in the zip along with
a make file. Type make when you are in the directory of the source and Borlands
should compile and link it all in the right order.
#define ID_FILE_NEW 1000 #define ID_FILE_OPEN 1001 #define ID_FILE_SAVE 1002 #define ID_FILE_EXIT 1003 #define ID_DO_SOMETHING 1004 #define ID_DO_SOMETHING_ELSE 1005 #define ID_HELP_ABOUT 1006 |
#include "section_1_5_1.h" ID_MENU MENU DISCARDABLE BEGIN POPUP "&File" BEGIN MENUITEM "&New", ID_FILE_NEW MENUITEM "&Open", ID_FILE_OPEN MENUITEM "&Save", ID_FILE_SAVE MENUITEM SEPARATOR MENUITEM "E&xit", ID_FILE_EXIT END POPUP "&Do" BEGIN MENUITEM "&Something", ID_DO_SOMETHING MENUITEM "Something &Else", ID_DO_SOMETHING_ELSE END POPUP "&Help" BEGIN MENUITEM "&About", ID_HELP_ABOUT END END |
#include <windows.h> #include "section_1_5_1.h" LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); static char gszClassName[] = "MyWindowClass"; static HINSTANCE ghInstance = NULL; int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { WNDCLASSEX WndClass; HWND hwnd; MSG Msg; ghInstance = hInstance; WndClass.cbSize = sizeof(WNDCLASSEX); WndClass.style = NULL; WndClass.lpfnWndProc = WndProc; WndClass.cbClsExtra = 0; WndClass.cbWndExtra = 0; WndClass.hInstance = ghInstance; WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION); WndClass.hCursor = LoadCursor(NULL, IDC_ARROW); WndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); WndClass.lpszMenuName = "ID_MENU"; WndClass.lpszClassName = gszClassName; WndClass.hIconSm = LoadIcon(NULL, IDI_APPLICATION); if(!RegisterClassEx(&WndClass)) { MessageBox(0, "Window Registration Failed!", "Error!", MB_ICONSTOP | MB_OK); return 0; } hwnd = CreateWindowEx( WS_EX_STATICEDGE, gszClassName, "Windows Title", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 320, 240, NULL, NULL, ghInstance, NULL); if(hwnd == NULL) { MessageBox(0, "Window Creation Failed!", "Error!", MB_ICONSTOP | MB_OK); return 0; } ShowWindow(hwnd, nCmdShow); UpdateWindow(hwnd); while(GetMessage(&Msg, NULL, 0, 0)) { TranslateMessage(&Msg); DispatchMessage(&Msg); } return Msg.wParam; } LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) { switch(Message) { case WM_CLOSE: DestroyWindow(hwnd); break; case WM_DESTROY: PostQuitMessage(0); break; case WM_COMMAND: switch(LOWORD(wParam)) { case ID_FILE_NEW: MessageBox(hwnd, "New File", "Menu", 0); break; case ID_FILE_OPEN: MessageBox(hwnd, "Open File", "Menu", 0); break; case ID_FILE_SAVE: MessageBox(hwnd, "Save File", "Menu", 0); break; case ID_FILE_EXIT: PostQuitMessage(0); case ID_DO_SOMETHING: MessageBox(hwnd, "Do Something", "Menu", 0); break; case ID_DO_SOMETHING_ELSE: MessageBox(hwnd, "Do Something Else", "Menu", 0); break; case ID_HELP_ABOUT: MessageBox(hwnd, "Written By AZTEK", "About", 0); break; } break; default: return DefWindowProc(hwnd, Message, wParam, lParam); } return 0; } |
Using resource menus are great if you have a menu that won't change. Some applications
although require menus that can be made on the spot. This might be used to add or
delete items from the menu or to make some items gray.
#define ID_FILE_NEW 1000 #define ID_FILE_OPEN 1001 #define ID_FILE_SAVE 1002 #define ID_FILE_EXIT 1003 #define ID_DO_SOMETHING 1004 #define ID_DO_SOMETHING_ELSE 1005 #define ID_HELP_ABOUT 1006 |
#include <windows.h> #include "section_1_5_2.h" LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); static char gszClassName[] = "MyWindowClass"; static HINSTANCE ghInstance = NULL; int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { WNDCLASSEX WndClass; HWND hwnd; MSG Msg; ghInstance = hInstance; WndClass.cbSize = sizeof(WNDCLASSEX); WndClass.style = NULL; WndClass.lpfnWndProc = WndProc; WndClass.cbClsExtra = 0; WndClass.cbWndExtra = 0; WndClass.hInstance = ghInstance; WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION); WndClass.hCursor = LoadCursor(NULL, IDC_ARROW); WndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); WndClass.lpszMenuName = NULL; WndClass.lpszClassName = gszClassName; WndClass.hIconSm = LoadIcon(NULL, IDI_APPLICATION); if(!RegisterClassEx(&WndClass)) { MessageBox(0, "Window Registration Failed!", "Error!", MB_ICONSTOP | MB_OK); return 0; } hwnd = CreateWindowEx( WS_EX_STATICEDGE, gszClassName, "Windows Title", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 320, 240, NULL, NULL, ghInstance, NULL); if(hwnd == NULL) { MessageBox(0, "Window Creation Failed!", "Error!", MB_ICONSTOP | MB_OK); return 0; } ShowWindow(hwnd, nCmdShow); UpdateWindow(hwnd); while(GetMessage(&Msg, NULL, 0, 0)) { TranslateMessage(&Msg); DispatchMessage(&Msg); } return Msg.wParam; } LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) { HMENU hMenu, hSubMenu; switch(Message) { case WM_CLOSE: DestroyWindow(hwnd); break; case WM_DESTROY: PostQuitMessage(0); break; case WM_CREATE: hMenu = CreateMenu(); hSubMenu = CreatePopupMenu(); AppendMenu(hSubMenu, MF_STRING, ID_FILE_NEW, "&New"); AppendMenu(hSubMenu, MF_STRING, ID_FILE_OPEN, "&Open"); AppendMenu(hSubMenu, MF_STRING, ID_FILE_SAVE, "&Save"); AppendMenu(hSubMenu, MF_SEPARATOR, 0, 0); AppendMenu(hSubMenu, MF_STRING, ID_FILE_EXIT, "E&xit"); AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT)hSubMenu, "&File"); hSubMenu = CreatePopupMenu(); AppendMenu(hSubMenu, MF_STRING, ID_DO_SOMETHING, "&Something"); AppendMenu(hSubMenu, MF_STRING, ID_DO_SOMETHING_ELSE, "Something &Else"); AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT)hSubMenu, "&Do"); hSubMenu = CreatePopupMenu(); AppendMenu(hSubMenu, MF_STRING, ID_HELP_ABOUT, "&About"); AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT)hSubMenu, "&Help"); SetMenu(hwnd, hMenu); break; case WM_COMMAND: switch(LOWORD(wParam)) { case ID_FILE_NEW: MessageBox(hwnd, "New File", "Menu", 0); break; case ID_FILE_OPEN: MessageBox(hwnd, "Open File", "Menu", 0); break; case ID_FILE_SAVE: MessageBox(hwnd, "Save File", "Menu", 0); break; case ID_FILE_EXIT: PostQuitMessage(0); case ID_DO_SOMETHING: MessageBox(hwnd, "Do Something", "Menu", 0); break; case ID_DO_SOMETHING_ELSE: MessageBox(hwnd, "Do Something Else", "Menu", 0); break; case ID_HELP_ABOUT: MessageBox(hwnd, "Written By AZTEK", "About", 0); break; } break; default: return DefWindowProc(hwnd, Message, wParam, lParam); } return 0; } |
Dialogs are a special kind of windows message box where you have a lot more control
than just a title and some text. In dialogs you can have edit boxes, check boxes,
icons, bitmaps, change colors, etc. It is easiest to design dialog boxes using a
resource editor, you can find some in the Tools Section.
#define ID_FILE_EXIT 1000 #define ID_HELP_ABOUT 1001 #define IDOK 2000 #define IDEMAIL 2001 #define IDAZTEK 2003 #define IDBSRF 2004 |
#include "section_1_6.h" ABOUTDLG DIALOG 19, 17, 182, 71 STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "About" FONT 8, "MS Sans Serif" BEGIN CTEXT "Written by AZTEK", 101, 17, 30, 81, 11 GROUPBOX "About", 102, 11, 11, 95, 48, WS_TABSTOP DEFPUSHBUTTON "&Ok", IDOK, 112, 6, 64, 14 PUSHBUTTON "&E-mail AZTEK", IDEMAIL, 112, 21, 64, 14 PUSHBUTTON "Visit &AZTEK", IDAZTEK, 112, 36, 64, 14 PUSHBUTTON "Visit &Blacksun", IDBSRF, 112, 51, 64, 14 END ID_MENU MENU BEGIN POPUP "&File" BEGIN MENUITEM "E&xit", ID_FILE_EXIT END POPUP "&Help" BEGIN MENUITEM "&About", ID_HELP_ABOUT END END |
#include <windows.h> #include "section_1_6.h" LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); BOOL CALLBACK DlgProc(HWND, UINT, WPARAM, LPARAM); static char gszClassName[] = "MyWindowClass"; static HINSTANCE ghInstance = NULL; int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { WNDCLASSEX WndClass; HWND hwnd; MSG Msg; ghInstance = hInstance; WndClass.cbSize = sizeof(WNDCLASSEX); WndClass.style = NULL; WndClass.lpfnWndProc = WndProc; WndClass.cbClsExtra = 0; WndClass.cbWndExtra = 0; WndClass.hInstance = ghInstance; WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION); WndClass.hCursor = LoadCursor(NULL, IDC_ARROW); WndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); WndClass.lpszMenuName = NULL; WndClass.lpszClassName = gszClassName; WndClass.hIconSm = LoadIcon(NULL, IDI_APPLICATION); if(!RegisterClassEx(&WndClass)) { MessageBox(0, "Window Registration Failed!", "Error!", MB_ICONSTOP | MB_OK); return 0; } hwnd = CreateWindowEx( WS_EX_STATICEDGE, gszClassName, "Windows Title", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 320, 240, NULL, NULL, ghInstance, NULL); if(hwnd == NULL) { MessageBox(0, "Window Creation Failed!", "Error!", MB_ICONSTOP | MB_OK); return 0; } ShowWindow(hwnd, nCmdShow); UpdateWindow(hwnd); while(GetMessage(&Msg, NULL, 0, 0)) { TranslateMessage(&Msg); DispatchMessage(&Msg); } return Msg.wParam; } LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) { switch(Message) { case WM_COMMAND: switch(LOWORD(wParam)) { case ID_FILE_EXIT: PostMessage(hwnd, WM_CLOSE, 0, 0); break; case ID_HELP_ABOUT: DialogBox(ghInstance, "ABOUTDLG", hwnd, DlgProc); break; } break; case WM_CLOSE: DestroyWindow(hwnd); break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hwnd, Message, wParam, lParam); } return 0; } BOOL CALLBACK DlgProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) { switch(Message) { case WM_INITDIALOG: return TRUE; case WM_COMMAND: switch(LOWORD(wParam)) { case IDOK: EndDialog(hwnd, IDOK); return TRUE; case IDEMAIL: ShellExecute(hwnd, "open", "mailto:aztek@faction7.com", 0, 0, 0); EndDialog(hwnd, IDEMAIL); return TRUE; case IDAZTEK: ShellExecute(hwnd, "open", "http://aztek.faction7.com", 0, 0, 0); EndDialog(hwnd, IDAZTEK); return TRUE; case IDBSRF: ShellExecute(hwnd, "open", "http://blacksun.box.sk", 0, 0, 0); EndDialog(hwnd, IDBSRF); return TRUE; } break; } return FALSE; } |
Controls are just child windows like buttons, checkboxess, edit boxes, etc. For
each control we make a new window using CreateWindowEx() but these are childs of
the first main window and not new windows.
#include <windows.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); static char gszClassName[] = "MyWindowClass"; static HINSTANCE ghInstance = NULL; int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { WNDCLASSEX WndClass; HWND hwnd; MSG Msg; ghInstance = hInstance; WndClass.cbSize = sizeof(WNDCLASSEX); WndClass.style = NULL; WndClass.lpfnWndProc = WndProc; WndClass.cbClsExtra = 0; WndClass.cbWndExtra = 0; WndClass.hInstance = ghInstance; WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION); WndClass.hCursor = LoadCursor(NULL, IDC_ARROW); WndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); WndClass.lpszMenuName = NULL; WndClass.lpszClassName = gszClassName; WndClass.hIconSm = LoadIcon(NULL, IDI_APPLICATION); if(!RegisterClassEx(&WndClass)) { MessageBox(0, "Window Registration Failed!", "Error!", MB_ICONSTOP | MB_OK); return 0; } hwnd = CreateWindowEx( WS_EX_STATICEDGE, gszClassName, "Windows Title", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 320, 240, NULL, NULL, ghInstance, NULL); if(hwnd == NULL) { MessageBox(0, "Window Creation Failed!", "Error!", MB_ICONSTOP | MB_OK); return 0; } ShowWindow(hwnd, nCmdShow); UpdateWindow(hwnd); while(GetMessage(&Msg, NULL, 0, 0)) { TranslateMessage(&Msg); DispatchMessage(&Msg); } return Msg.wParam; } LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) { HWND hButton, hCombo, hEdit, hList, hScroll, hStatic; switch(Message) { case WM_CREATE: hButton = CreateWindowEx( NULL, "Button", "Button", WS_BORDER | WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 0, 0, 100, 30, hwnd, NULL, ghInstance, NULL); hCombo = CreateWindowEx( NULL, "ComboBox", "", WS_BORDER | WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST, 0, 30, 100, 100, hwnd, NULL, ghInstance, NULL); hEdit = CreateWindowEx( NULL, "Edit", "Edit", WS_BORDER | WS_CHILD | WS_VISIBLE, 0, 60, 100, 30, hwnd, NULL, ghInstance, NULL); hList = CreateWindowEx( NULL, "ListBox", "", WS_BORDER | WS_CHILD | WS_VISIBLE, 100, 0, 100, 200, hwnd, NULL, ghInstance, NULL); hScroll = CreateWindowEx( NULL, "ScrollBar", "", WS_BORDER | WS_CHILD | WS_VISIBLE | SBS_VERT, 210, 0, 100, 200, hwnd, NULL, ghInstance, NULL); hStatic = CreateWindowEx( NULL, "Static", "", WS_BORDER | WS_CHILD | WS_VISIBLE | SS_BLACKRECT, 0, 90, 100, 30, hwnd, NULL, ghInstance, NULL); break; case WM_CLOSE: DestroyWindow(hwnd); break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hwnd, Message, wParam, lParam); } return 0; } |
In this section I will discus how to display a bitmap file in your program. The first way I will discus is the static way using a resource. The second way is to do it dynamicly using a actual bitmap file. Throughout our examples here I will use this bitmap file.
2.1.1 ResourceUsing a bitmap from a resource file is probbaly the best way to do it unless you
need the expandibility of a dynamic bitmap file.
#define IDB_BITMAP1 1000 |
#include "section_2_1_1.h" IDB_BITMAP1 BITMAP "bitmap.bmp" |
#include <windows.h> #include "section_2_1_1.h" LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); static char gszClassName[] = "MyWindowClass"; static HINSTANCE ghInstance = NULL; int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { WNDCLASSEX WndClass; HWND hwnd; MSG Msg; ghInstance = hInstance; WndClass.cbSize = sizeof(WNDCLASSEX); WndClass.style = NULL; WndClass.lpfnWndProc = WndProc; WndClass.cbClsExtra = 0; WndClass.cbWndExtra = 0; WndClass.hInstance = ghInstance; WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION); WndClass.hCursor = LoadCursor(NULL, IDC_ARROW); WndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); WndClass.lpszMenuName = NULL; WndClass.lpszClassName = gszClassName; WndClass.hIconSm = LoadIcon(NULL, IDI_APPLICATION); if(!RegisterClassEx(&WndClass)) { MessageBox(0, "Window Registration Failed!", "Error!", MB_ICONSTOP | MB_OK); return 0; } hwnd = CreateWindowEx( WS_EX_STATICEDGE, gszClassName, "Windows Title", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 320, 240, NULL, NULL, ghInstance, NULL); if(hwnd == NULL) { MessageBox(0, "Window Creation Failed!", "Error!", MB_ICONSTOP | MB_OK); return 0; } ShowWindow(hwnd, nCmdShow); UpdateWindow(hwnd); while(GetMessage(&Msg, NULL, 0, 0)) { TranslateMessage(&Msg); DispatchMessage(&Msg); } return Msg.wParam; } LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) { HBITMAP hBitmap; HWND hBmpStat; switch(Message) { case WM_CREATE: hBitmap = LoadBitmap(ghInstance, MAKEINTRESOURCE(IDB_BITMAP1)); hBmpStat = CreateWindowEx( NULL, "Static", "", WS_VISIBLE | WS_CHILD | SS_BITMAP, 0, 0, 0, 0, hwnd, NULL, ghInstance, NULL); SendMessage(hBmpStat, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM) hBitmap); break; case WM_CLOSE: DestroyWindow(hwnd); break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hwnd, Message, wParam, lParam); } return 0; } |
Loading a bitmap from a file is alot like loading one from a resource, in fact there
is actually only 1 line change.
#include <windows.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); static char gszClassName[] = "MyWindowClass"; static HINSTANCE ghInstance = NULL; int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { WNDCLASSEX WndClass; HWND hwnd; MSG Msg; ghInstance = hInstance; WndClass.cbSize = sizeof(WNDCLASSEX); WndClass.style = NULL; WndClass.lpfnWndProc = WndProc; WndClass.cbClsExtra = 0; WndClass.cbWndExtra = 0; WndClass.hInstance = ghInstance; WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION); WndClass.hCursor = LoadCursor(NULL, IDC_ARROW); WndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); WndClass.lpszMenuName = NULL; WndClass.lpszClassName = gszClassName; WndClass.hIconSm = LoadIcon(NULL, IDI_APPLICATION); if(!RegisterClassEx(&WndClass)) { MessageBox(0, "Window Registration Failed!", "Error!", MB_ICONSTOP | MB_OK); return 0; } hwnd = CreateWindowEx( WS_EX_STATICEDGE, gszClassName, "Windows Title", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 320, 240, NULL, NULL, ghInstance, NULL); if(hwnd == NULL) { MessageBox(0, "Window Creation Failed!", "Error!", MB_ICONSTOP | MB_OK); return 0; } ShowWindow(hwnd, nCmdShow); UpdateWindow(hwnd); while(GetMessage(&Msg, NULL, 0, 0)) { TranslateMessage(&Msg); DispatchMessage(&Msg); } return Msg.wParam; } LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) { HBITMAP hBitmap; HWND hBmpStat; switch(Message) { case WM_CREATE: hBitmap = (HBITMAP) LoadImage(NULL, "bitmap.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); hBmpStat = CreateWindowEx( NULL, "Static", "", WS_VISIBLE | WS_CHILD | SS_BITMAP, 0, 0, 0, 0, hwnd, NULL, ghInstance, NULL); SendMessage(hBmpStat, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM) hBitmap); break; case WM_CLOSE: DestroyWindow(hwnd); break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hwnd, Message, wParam, lParam); } return 0; } |
The "Big Thing" for windows programs right now seems to be to put a
icon in the system tray. In this next example we will go over putting a icon in
in the system tray and having a menu pop up when the user right clicks on the icon.
#include "section_2_2.h" IDI_ICON1 ICON "icon.ico" |
#define WM_TRAYNOTIFY (WM_USER + 1000) #define IDI_ICON1 1000 #define IDC_TRAYICON 1001 #define IDM_EXIT 1002 #define IDM_ABOUT 1003 |
#include <windows.h> #include "section_2_2.h" LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); static char gszClassName[] = "MyWindowClass"; static HINSTANCE ghInstance = NULL; HMENU hMenu; int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { WNDCLASSEX WndClass; HWND hwnd; MSG Msg; ghInstance = hInstance; WndClass.cbSize = sizeof(WNDCLASSEX); WndClass.style = NULL; WndClass.lpfnWndProc = WndProc; WndClass.cbClsExtra = 0; WndClass.cbWndExtra = 0; WndClass.hInstance = ghInstance; WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION); WndClass.hCursor = LoadCursor(NULL, IDC_ARROW); WndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); WndClass.lpszMenuName = NULL; WndClass.lpszClassName = gszClassName; WndClass.hIconSm = LoadIcon(NULL, IDI_APPLICATION); if(!RegisterClassEx(&WndClass)) { MessageBox(0, "Window Registration Failed!", "Error!", MB_ICONSTOP | MB_OK); return 0; } hwnd = CreateWindowEx( WS_EX_STATICEDGE, gszClassName, "Windows Title", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 320, 240, NULL, NULL, ghInstance, NULL); if(hwnd == NULL) { MessageBox(0, "Window Creation Failed!", "Error!", MB_ICONSTOP | MB_OK); return 0; } ShowWindow(hwnd, nCmdShow); UpdateWindow(hwnd); while(GetMessage(&Msg, NULL, 0, 0)) { TranslateMessage(&Msg); DispatchMessage(&Msg); } return Msg.wParam; } LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) { NOTIFYICONDATA notifyIconData; switch(Message) { case WM_CREATE: notifyIconData.cbSize = sizeof(NOTIFYICONDATA); notifyIconData.hWnd = hwnd; notifyIconData.uID = IDC_TRAYICON; notifyIconData.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP; notifyIconData.uCallbackMessage = WM_TRAYNOTIFY; notifyIconData.hIcon = (HICON) LoadImage( ghInstance, MAKEINTRESOURCE(IDI_ICON1), IMAGE_ICON, 16, 16, NULL); lstrcpyn(notifyIconData.szTip, "Tray Icon", sizeof(notifyIconData.szTip)); Shell_NotifyIcon(NIM_ADD, ¬ifyIconData); hMenu = CreatePopupMenu(); AppendMenu(hMenu, MF_STRING, IDM_EXIT, "E&xit"); AppendMenu(hMenu, MF_SEPARATOR, NULL, NULL); AppendMenu(hMenu, MF_STRING, IDM_ABOUT, "&About"); break; case WM_TRAYNOTIFY: switch(wParam) { case IDC_TRAYICON: switch(lParam) { case WM_LBUTTONDOWN: case WM_RBUTTONDOWN: POINT point; GetCursorPos(&point); SetForegroundWindow(hwnd); TrackPopupMenu(hMenu, TPM_RIGHTALIGN, point.x, point.y, NULL, hwnd, NULL); SendMessage(hwnd, WM_NULL, NULL, NULL); break; } break; } break; case WM_COMMAND: switch(wParam) { case IDM_EXIT: SendMessage(hwnd, WM_CLOSE, NULL, NULL); break; case IDM_ABOUT: MessageBox( hwnd, "Example of a windows system tray program\r\nWritten by AZTEK", "About", NULL); break; break; } break; case WM_CLOSE: DestroyWindow(hwnd); break; case WM_DESTROY: notifyIconData.cbSize = sizeof(NOTIFYICONDATA); notifyIconData.hWnd = hwnd; notifyIconData.uID = IDC_TRAYICON; Shell_NotifyIcon(NIM_DELETE, ¬ifyIconData); DestroyMenu(hMenu); PostQuitMessage(0); break; default: return DefWindowProc(hwnd, Message, wParam, lParam); } return 0; } |
In this section I will cover how to add a toolbar to you window. I will first go over adding custom buttons from a bitmap file. The I will go over common buttons that are predefined.
2.3.1 Custom ButtonsCustom buttons are just a bitmap image that is devided up in 16x16 squares. In
this next example, I use this bitmap file.
#include "section_2_3.h" IDB_TOOLBAR BITMAP "toolbar.bmp" |
#define IDC_TOOLBAR 1000 #define IDB_TOOLBAR 1001 #define IDM_BUTTON0 1002 #define IDM_BUTTON1 1003 #define IDM_BUTTON2 1004 #define IDM_BUTTON3 1005 #define IDM_BUTTON4 1006 #define IDM_BUTTON5 1007 #define IDM_BUTTON6 1008 #define IDM_BUTTON7 1009 |
#include <windows.h> #include <commctrl.h> #include "section_2_3_1.h" LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); static char gszClassName[] = "MyWindowClass"; static HINSTANCE ghInstance = NULL; HWND ghToolBar; int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { WNDCLASSEX WndClass; HWND hwnd; MSG Msg; ghInstance = hInstance; WndClass.cbSize = sizeof(WNDCLASSEX); WndClass.style = NULL; WndClass.lpfnWndProc = WndProc; WndClass.cbClsExtra = 0; WndClass.cbWndExtra = 0; WndClass.hInstance = ghInstance; WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION); WndClass.hCursor = LoadCursor(NULL, IDC_ARROW); WndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); WndClass.lpszMenuName = NULL; WndClass.lpszClassName = gszClassName; WndClass.hIconSm = LoadIcon(NULL, IDI_APPLICATION); if(!RegisterClassEx(&WndClass)) { MessageBox(0, "Window Registration Failed!", "Error!", MB_ICONSTOP | MB_OK); return 0; } hwnd = CreateWindowEx( WS_EX_STATICEDGE, gszClassName, "Windows Title", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 320, 240, NULL, NULL, ghInstance, NULL); if(hwnd == NULL) { MessageBox(0, "Window Creation Failed!", "Error!", MB_ICONSTOP | MB_OK); return 0; } ShowWindow(hwnd, nCmdShow); UpdateWindow(hwnd); while(GetMessage(&Msg, NULL, 0, 0)) { TranslateMessage(&Msg); DispatchMessage(&Msg); } return Msg.wParam; } LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) { switch(Message) { case WM_CREATE: TBADDBITMAP tbAddBitmap; TBBUTTON tbButton[8]; InitCommonControls(); ghToolBar = CreateWindowEx( NULL, TOOLBARCLASSNAME, NULL, WS_CHILD | WS_VISIBLE, 0, 0, 0, 0, hwnd, (HMENU)IDC_TOOLBAR, ghInstance, NULL); SendMessage(ghToolBar, TB_BUTTONSTRUCTSIZE, (WPARAM) sizeof(TBBUTTON), NULL); tbAddBitmap.hInst = ghInstance; tbAddBitmap.nID = IDB_TOOLBAR; SendMessage(ghToolBar, TB_ADDBITMAP, 0, (LPARAM) &tbAddBitmap); ZeroMemory(tbButton, sizeof(tbButton)); tbButton[0].iBitmap = 0; tbButton[0].fsState = TBSTATE_ENABLED; tbButton[0].fsStyle = TBSTYLE_BUTTON; tbButton[0].idCommand = IDM_BUTTON0; tbButton[1].iBitmap = 1; tbButton[1].fsState = TBSTATE_ENABLED; tbButton[1].fsStyle = TBSTYLE_BUTTON; tbButton[1].idCommand = IDM_BUTTON1; tbButton[2].fsStyle = TBSTYLE_SEP; tbButton[3].iBitmap = 2; tbButton[3].fsState = TBSTATE_ENABLED; tbButton[3].fsStyle = TBSTYLE_BUTTON; tbButton[3].idCommand = IDM_BUTTON2; tbButton[4].iBitmap = 3; tbButton[4].fsState = TBSTATE_ENABLED; tbButton[4].fsStyle = TBSTYLE_BUTTON; tbButton[4].idCommand = IDM_BUTTON3; tbButton[5].fsStyle = TBSTYLE_SEP; tbButton[6].iBitmap = 4; tbButton[6].fsState = TBSTATE_ENABLED; tbButton[6].fsStyle = TBSTYLE_BUTTON; tbButton[6].idCommand = IDM_BUTTON4; tbButton[7].iBitmap = 5; tbButton[7].fsState = TBSTATE_ENABLED; tbButton[7].fsStyle = TBSTYLE_BUTTON; tbButton[7].idCommand = IDM_BUTTON5; SendMessage(ghToolBar, TB_ADDBUTTONS, 8, (LPARAM) &tbButton); break; case WM_COMMAND: switch(LOWORD(wParam)) { case IDM_BUTTON0: case IDM_BUTTON1: case IDM_BUTTON2: case IDM_BUTTON3: case IDM_BUTTON4: case IDM_BUTTON5: MessageBox(hwnd, "A Button was clicked.", "Toolbar Message", MB_ICONINFORMATION | MB_OK); break; } break; case WM_SIZE: SendMessage(ghToolBar, TB_AUTOSIZE, 0, 0); break; case WM_CLOSE: DestroyWindow(hwnd); break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hwnd, Message, wParam, lParam); } return 0; } |
It would be a real pain if you had to make new New, Open, Save, etc. buttons for
every application you write, so they came up with common buttons. Common buttons
are buttons used by alot of apps. Below I have a common button program example,
I will explain the new parts but its pretty much the same as the custom button example
above.
#define IDC_TOOLBAR 1000 #define IDM_BUTTON0 1001 #define IDM_BUTTON1 1002 #define IDM_BUTTON2 1003 #define IDM_BUTTON3 1004 #define IDM_BUTTON4 1005 #define IDM_BUTTON5 1006 #define IDM_BUTTON6 1007 #define IDM_BUTTON7 1008 |
#include <windows.h> #include <commctrl.h> #include "section_2_3_2.h" LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); static char gszClassName[] = "MyWindowClass"; static HINSTANCE ghInstance = NULL; HWND ghToolBar; int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { WNDCLASSEX WndClass; HWND hwnd; MSG Msg; ghInstance = hInstance; WndClass.cbSize = sizeof(WNDCLASSEX); WndClass.style = NULL; WndClass.lpfnWndProc = WndProc; WndClass.cbClsExtra = 0; WndClass.cbWndExtra = 0; WndClass.hInstance = ghInstance; WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION); WndClass.hCursor = LoadCursor(NULL, IDC_ARROW); WndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); WndClass.lpszMenuName = NULL; WndClass.lpszClassName = gszClassName; WndClass.hIconSm = LoadIcon(NULL, IDI_APPLICATION); if(!RegisterClassEx(&WndClass)) { MessageBox(0, "Window Registration Failed!", "Error!", MB_ICONSTOP | MB_OK); return 0; } hwnd = CreateWindowEx( WS_EX_STATICEDGE, gszClassName, "Windows Title", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 320, 240, NULL, NULL, ghInstance, NULL); if(hwnd == NULL) { MessageBox(0, "Window Creation Failed!", "Error!", MB_ICONSTOP | MB_OK); return 0; } ShowWindow(hwnd, nCmdShow); UpdateWindow(hwnd); while(GetMessage(&Msg, NULL, 0, 0)) { TranslateMessage(&Msg); DispatchMessage(&Msg); } return Msg.wParam; } LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) { switch(Message) { case WM_CREATE: TBADDBITMAP tbAddBitmap; TBBUTTON tbButton[7]; InitCommonControls(); ghToolBar = CreateWindowEx( NULL, TOOLBARCLASSNAME, NULL, WS_CHILD | WS_VISIBLE, 0, 0, 0, 0, hwnd, (HMENU)IDC_TOOLBAR, ghInstance, NULL); SendMessage(ghToolBar, TB_BUTTONSTRUCTSIZE, (WPARAM) sizeof(TBBUTTON), NULL); tbAddBitmap.hInst = HINST_COMMCTRL; tbAddBitmap.nID = IDB_STD_SMALL_COLOR; SendMessage(ghToolBar, TB_ADDBITMAP, 0, (LPARAM) &tbAddBitmap); ZeroMemory(tbButton, sizeof(tbButton)); tbButton[0].iBitmap = STD_FILENEW; tbButton[0].fsState = TBSTATE_ENABLED; tbButton[0].fsStyle = TBSTYLE_BUTTON; tbButton[0].idCommand = IDM_BUTTON0; tbButton[1].iBitmap = STD_FILEOPEN; tbButton[1].fsState = TBSTATE_ENABLED; tbButton[1].fsStyle = TBSTYLE_BUTTON; tbButton[1].idCommand = IDM_BUTTON1; tbButton[3].iBitmap = STD_FILESAVE; tbButton[3].fsState = TBSTATE_ENABLED; tbButton[3].fsStyle = TBSTYLE_BUTTON; tbButton[3].idCommand = IDM_BUTTON2; tbButton[5].fsStyle = TBSTYLE_SEP; tbButton[4].iBitmap = STD_CUT; tbButton[4].fsState = TBSTATE_ENABLED; tbButton[4].fsStyle = TBSTYLE_BUTTON; tbButton[4].idCommand = IDM_BUTTON3; tbButton[6].iBitmap = STD_COPY; tbButton[6].fsState = TBSTATE_ENABLED; tbButton[6].fsStyle = TBSTYLE_BUTTON; tbButton[6].idCommand = IDM_BUTTON4; tbButton[7].iBitmap = STD_PASTE; tbButton[7].fsState = TBSTATE_ENABLED; tbButton[7].fsStyle = TBSTYLE_BUTTON; tbButton[7].idCommand = IDM_BUTTON5; SendMessage(ghToolBar, TB_ADDBUTTONS, 7, (LPARAM) &tbButton); break; case WM_COMMAND: switch(LOWORD(wParam)) { case IDM_BUTTON0: case IDM_BUTTON1: case IDM_BUTTON2: case IDM_BUTTON3: case IDM_BUTTON4: case IDM_BUTTON5: MessageBox(hwnd, "A Button was clicked.", "Toolbar Message", MB_ICONINFORMATION | MB_OK); break; } break; case WM_SIZE: SendMessage(ghToolBar, TB_AUTOSIZE, 0, 0); break; case WM_CLOSE: DestroyWindow(hwnd); break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hwnd, Message, wParam, lParam); } return 0; } |
We have all seen status bars. Most text editing programs have a statusbar. They
can be very useful, but they can also be one of the most abused thing in windows
programming.
#define IDC_STATBAR 1000 |
#include <windows.h> #include <commctrl.h> #include "section_2_4.h" LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); static char gszClassName[] = "MyWindowClass"; static HINSTANCE ghInstance = NULL; HWND ghStatBar; int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { WNDCLASSEX WndClass; HWND hwnd; MSG Msg; ghInstance = hInstance; WndClass.cbSize = sizeof(WNDCLASSEX); WndClass.style = NULL; WndClass.lpfnWndProc = WndProc; WndClass.cbClsExtra = 0; WndClass.cbWndExtra = 0; WndClass.hInstance = ghInstance; WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION); WndClass.hCursor = LoadCursor(NULL, IDC_ARROW); WndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); WndClass.lpszMenuName = NULL; WndClass.lpszClassName = gszClassName; WndClass.hIconSm = LoadIcon(NULL, IDI_APPLICATION); if(!RegisterClassEx(&WndClass)) { MessageBox(0, "Window Registration Failed!", "Error!", MB_ICONSTOP | MB_OK); return 0; } hwnd = CreateWindowEx( WS_EX_STATICEDGE, gszClassName, "Windows Title", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 320, 240, NULL, NULL, ghInstance, NULL); if(hwnd == NULL) { MessageBox(0, "Window Creation Failed!", "Error!", MB_ICONSTOP | MB_OK); return 0; } ShowWindow(hwnd, nCmdShow); UpdateWindow(hwnd); while(GetMessage(&Msg, NULL, 0, 0)) { TranslateMessage(&Msg); DispatchMessage(&Msg); } return Msg.wParam; } LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) { switch(Message) { case WM_CREATE: int iBarWidths[] = {100, 200, 300, -1}; InitCommonControls(); ghStatBar = CreateWindowEx( NULL, TOOLBARCLASSNAME, NULL, WS_CHILD | WS_VISIBLE, 0, 0, 0, 0, hwnd, (HMENU)IDC_TOOLBAR, ghInstance, NULL); SendMessage(ghStatBar, SB_SETPARTS, 4, (LPARAM) iBarWidths); SendMessage(ghStatBar, SB_SETTEXT, 0, (LPARAM) "Part 1"); SendMessage(ghStatBar, SB_SETTEXT, 1, (LPARAM) "Part 2"); SendMessage(ghStatBar, SB_SETTEXT, 2, (LPARAM) "Part 3"); SendMessage(ghStatBar, SB_SETTEXT, 3, (LPARAM) "Part 4"); break; case WM_SIZE: SendMessage(ghStatBar, WM_SIZE, 0, 0); break; case WM_CLOSE: DestroyWindow(hwnd); break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hwnd, Message, wParam, lParam); } return 0; } |
I like most of you are pretty low on cash most of the time. So I use a free compiler
from Borland. I also use the old Borland 5.02 the last one with an IDE. I also got
my hands on a copy of Visual C++ 6 ( not going to say how) which I didn't find all
that great and pretty intrusive. All of the examples in this tutorial were compiled
with the Borland Free Compiler v5.5 check the tools section for
a link to where you can download it. After you get the compiler set up correctly
just open up a command line and browse to where you unziped the tutorials. The compile
using:
C:\Cpp\tutorial\examples\section_1_2> bcc32 -tW section_1_2.cpp |
Every great programmer has to have a few good tools he uses. The first being
his compiler and IDE. Here I have listed a few tools I find that might be useful.
Wow I can't believe I finaly got this thing done. I hope this tutorial has helped
you all. I am looking forward to writing another one. To go over even more advanced
topics. I would like to give shout outs to all my felow Blacksun
Research Facility Members especialy Mikkkeee, DigitalFallout, Cyberwolf, and
SpiderMan. Also To all of those of you in #bsrf, #neworder, #linux, and #code who
wouldn't shut up until we help you with your questions :) And especially to cube
and the rest of the Box Network Team for
the great job they have done.
AZTEK