?? simple_window.html
字號:
WS_EX_CLIENTEDGE, g_szClassName, "The title of my window", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 240, 120, NULL, NULL, hInstance, NULL);</PRE><P>The first parameter (<CODE>WS_EX_CLIENTEDGE</CODE>) is the extended windows style, in thiscase I have set it to give it a sunken inner border around the window. Set itto <CODE>0</CODE> if you'd like to see the difference. Also play with other values tosee what they do.<P>Next we have the class name (<CODE>g_szClassName</CODE>), this tells the system what kindof window to create. Since we want to create a window from the class we just registered, we use the name of that class. After that we specify our window name or titlewhich is the text that will be displayed in the <I>Caption</I>, or <I>Title Bar</I> on our window.<P>The parameter we have as <CODE>WS_OVERLAPPEDWINDOW</CODE> is the <I>Window Style</I> parameter.There are quite a few of these and you should look them up and experiment tofind out what they do. These will be covered more later.<P>The next four parameters (<CODE>CW_USEDEFAULT, CW_USEDEFAULT, 320, 240</CODE>) are theX and Y co-ordinates for the top left corner of your window, and the widthand height of the window. I've set the X and Y values to <CODE>CW_USEDEFAULT</CODE>to let windows choosewhere on the screen to put the window. Remeber that the left of the screen is anX value of zero and it increases to the right; The top of the screen is a Y valueof zero which increases towards the bottom. The units are pixels, which isthe smallest unit a screen can display at a given resolution.<P>Next (<CODE>NULL, NULL, g_hInst, NULL</CODE>) we have the <I>Parent Window</I> handle, the menuhandle, the application instance handle, and a pointer to window creation data.In windows, the windows on your screen are arranged in a heirarchy of parent and childwindows. When you see a button on a window, the button is the <I>Child</I> and it is contained withinthe window that is it's <I>Parent</I>.In this example, the parent handle is <CODE>NULL</CODE> because we have no parent, this is our main or <I>Top Level</I> window.The menu is <CODE>NULL</CODE> for now since we don't have one yet. The instance handle isset to the value that is passed in as the first parameter to <CODE>WinMain()</CODE>. The creation data (which I almost never use) that can be used to send additional data to the window that is being created is also <CODE>NULL</CODE>.<P>If you're wondering what this magic <CODE>NULL</CODE> is, it's simply defined as <CODE>0</CODE> (zero). Actually, in C it's defined as <CODE>((void*)0)</CODE>, since it's intended foruse with pointers. Therefore you will possibly get warnings if you use NULL for integervalues, depending on your compiler and the warning level settings. You can choose to ignorethe warnings, or just use <CODE>0</CODE> instead.<P>Number one cause of people not knowing what the heck is wrong with their programs is probablythat they didn't check the return values of their calls to see if they failed or not.<CODE>CreateWindow()</CODE> <I>will</I> fail at some point even if you're an experiancedcoder, simply because there are lots of mistakes that are easy to make. Untill you learnhow to quickly identify those mistakes, at least give yourself the chance of figuring outwhere things go wrong, and <B>Always check return values!</B><PRE CLASS="SNIP"> if(hwnd == NULL) { MessageBox(NULL, "Window Creation Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK); return 0; }</PRE><P>After we've created the window and checked to make sure we have a valid handlewe show the window, using the last parameter in <CODE>WinMain()</CODE> and then update it toensure that it has properly redrawn itself on the screen.<PRE CLASS="SNIP"> ShowWindow(hwnd, nCmdShow); UpdateWindow(hwnd);</PRE><P>The <CODE>nCmdShow</CODE> parameter is optional, you could simply pass in <CODE>SW_SHOWNORMAL</CODE>all the time and be done with it. However using the parameter passed into <CODE>WinMain()</CODE> giveswhoever is running your program to specify whether or not they want your window to start offvisible, maximized, minimized, etc... You will find options for these in the properties ofwindows shortcuts, and this parameter is how the choice is carried out.<H2>Step 3: The Message Loop</H2><P>This is the heart of the whole program, pretty much everything that your program doespasses through this point of control.<PRE CLASS="SNIP"> while(GetMessage(&Msg, NULL, 0, 0) > 0) { TranslateMessage(&Msg); DispatchMessage(&Msg); } return Msg.wParam;</PRE><P><CODE>GetMessage()</CODE> gets a message from your application's message queue. Any time the usermoves the mouse, types on the keyboard, clicks on your window's menu, or does anynumber of other things, messages are generated by the system and entered into your program's message queue. By calling <CODE>GetMessage()</CODE> you are requesting the nextavailable message to be removed from the queue and returned to you for processing. If thereis no message, <CODE>GetMessage()</CODE> <I>Blocks</I>. If you are unfamiliar with the term, itmeans that it waits untill there is a message, and then returns it to you.<P><CODE>TranslateMessage()</CODE> does some additional processing on keyboardevents like generating <CODE>WM_CHAR</CODE> messages to go along with <CODE>WM_KEYDOWN</CODE> messages.Finally <CODE>DispatchMessage()</CODE> sends the message out to the window that themessage was sent to. This could be our main window or it could be another one, or a control,and in some cases a window that was created behind the scenes by the sytem or another program.This isn't something you need to worry about because all we are concerned with is thatwe get the message and send it out, the system takes care of the rest making sure itgets to the proper window.<H2>Step 4: the Window Procedure</H2>If the message loop is the heart of the program, the window procedure is the brain.This is where all the messages that are sent to our window get processed.<PRE CLASS="SNIP">LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){ switch(msg) { case WM_CLOSE: DestroyWindow(hwnd); break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hwnd, msg, wParam, lParam); } return 0;}</PRE><P>The window procedure is called for each message, the <CODE>HWND</CODE> parameter isthe handle of your window, the one that the message applies to. This is important since you might have two or more windows of the same class and they will use thesame window procedure (<CODE>WndProc()</CODE>). The difference is that the parameter<CODE>hwnd</CODE> will be different depending on which window it is. For example whenwe get the <CODE>WM_CLOSE</CODE> message we destroy the window. Since we use the window handlethat we received as the first paramter, any other windows will not be affected, only the one that the message was intended for.<P><CODE>WM_CLOSE</CODE> is sent when the user presses the Close Button <IMG SRC="images/button_close.gif" ALT="[x]"> or types Alt-F4. This will cause the windowto be destroyed by default, but I like to handle it explicitly, since this is the perfectspot to do cleanup checks, or ask the user to save files etc. before exiting the program.<P>When we call <CODE>DestroyWindow()</CODE> the system sends the <CODE>WM_DESTROY</CODE>message to the window getting destroyed, in this case it's our window, and then destroysany remaining child windows before finally removing our window from the system. Since thisis the only window in our program, we are all done and we want the program to exit, so wecall <CODE>PostQuitMessage()</CODE>. This posts the <CODE>WM_QUIT</CODE> message to themessage loop. We never receive this message, because it causes <CODE>GetMessage()</CODE>to return <CODE>FALSE</CODE>, and as you'll see in our message loop code, when that happenswe stop processing messages and return the final result code, the <CODE>wParam</CODE> of <CODE>WM_QUIT</CODE> which happens to be the value we passed into <CODE>PostQuitMessage()</CODE>.The return value is only really useful if your program is designed to be called by another programand you want to return a specific value.<H2>Step 5: There is no Step 5</H2><P>Phew. Well that's it! If I haven't explained stuff clearly enough yet, justhang in there and hopefully things will become more clear as we get into moreusefull programs.<HR><FONT SIZE="-1">Copyright © 1998-2003, Brook Miles (<A HREF="mailto:forger(nospam)winprog.org">theForger</A>). All rights reserved.</FONT><SCRIPT language="JavaScript"><!-- var re = /\(nospam\)/ig; var str; for(i = 0;i < document.links.length;i++) { str = "" + document.links(i).href; if(str.search(re) != -1) document.links(i).href = str.replace(re, "@"); str = "" + document.links(i).innerHTML; if(str.search(re) != -1) document.links(i).innerHTML = str.replace(re, "@"); }--></SCRIPT></BODY></HTML>
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -