📄 atl under the hood - part 5.mht
字号:
=
href=3D"http://www.codeproject.com/script/profile/add_bookmark.asp?t=3D0&=
amp;ct=3D%2Fatl%2Fatl%5Funderthehood%5F5%2Easp&guid=3Datl%5Fundertheh=
ood%5F5%2Fatl10%2F27%2F2002">Bookmark=20
this</A></TD></TR></TR>
<TR vAlign=3Dtop>
<TD><IMG height=3D16=20
src=3D"http://www.codeproject.com/images/mail.gif" =
width=3D16></TD>
<TD class=3DSmallText><A=20
=
href=3D"http://www.codeproject.com/script/recommend/form.asp?guid=3Datl%5=
Funderthehood%5F5%2Fatl10%2F27%2F2002">Send=20
to a friend</A></TD></TR>
<TR vAlign=3Dtop>
<TD></TD>
<TD></TD></TR>
<TR vAlign=3Dtop>
<TD></TD>
<TD class=3DInfoBarHeader>My Profile</TD></TR>
<TR>
<TD bgColor=3Dblack colSpan=3D2><IMG height=3D1=20
src=3D"http://www.codeproject.com/images/space.gif"=20
width=3D1></TD></TR>
<TR vAlign=3Dtop>
<TD><IMG height=3D16=20
=
src=3D"http://www.codeproject.com/images/profile_small.gif"=20
width=3D16></TD>
<TD class=3DsmallText><A=20
=
href=3D"http://www.codeproject.com/script/profile/modify.asp?ct=3D/atl/at=
l_underthehood_5.asp">My=20
Settings</A></TD></TR>
<TR vAlign=3Dtop>
<TD><IMG height=3D16=20
=
src=3D"http://www.codeproject.com/images/submit_small.gif"=20
width=3D16></TD>
<TD class=3DsmallText><A=20
=
href=3D"http://www.codeproject.com/script/articles/list_articles.asp?user=
id=3D273403">My=20
Articles</A></TD></TR>
<TR vAlign=3Dtop>
<TD><IMG height=3D16=20
=
src=3D"http://www.codeproject.com/images/bookmarks.gif"=20
width=3D16></TD>
<TD class=3DsmallText><A=20
=
href=3D"http://www.codeproject.com/script/profile/bookmark_list.asp">My=20
Bookmarks</A></TD></TR>
<TR vAlign=3Dtop>
<TD><IMG height=3D16=20
=
src=3D"http://www.codeproject.com/images/logoff_small.gif"=20
width=3D16></TD>
<TD class=3DsmallText><A=20
=
href=3D"http://www.codeproject.com/script/profile/logoff.asp?ct=3D/atl/at=
l_underthehood_5.asp">Sign=20
out</A></TD></TR>
<TR>
<TD bgColor=3Dblack colSpan=3D2><IMG height=3D1=20
src=3D"http://www.codeproject.com/images/space.gif"=20
width=3D1></TD></TR></TBODY></TABLE></TD></TR>
<TR>
<TD> </TD></TR>
<TR>
<TD>
<CENTER><A=20
=
href=3D"http://www.codeproject.com/script/admentor/admentorredir.asp?id=3D=
171&way=3Dban"=20
target=3D_blank><IMG height=3D600=20
alt=3D"MSDN Magazine - Your guide to Microsoft tools, =
development environments, and technologies for Windows and the Web."=20
=
src=3D"http://www.codeproject.com/script/admentor/images/mm120_600_codepr=
ot3.gif"=20
width=3D120 =
border=3D0></A><BR></CENTER><BR></TD></TR></TBODY></TABLE></TD>
<TD width=3D5 rowSpan=3D2><IMG height=3D1=20
src=3D"http://www.codeproject.com/images/space.gif" width=3D5> =
</TD>
<TD align=3Dright width=3D"100%" bgColor=3Dwhite>
<TABLE width=3D"100%">
<TBODY>
<TR>
<TD class=3DsmallText vAlign=3Dtop noWrap></TD>
<TD noWrap align=3Dright><A name=3D__top></A>
<TABLE>
<TBODY>
<TR>
<TD class=3DsmallText align=3Dright>20 members have =
rated this=20
article. Result:</TD>
<TD>
<TABLE cellSpacing=3D0 cellPadding=3D0 border=3D2>
<TBODY>
<TR>
<TD><IMG height=3D5=20
=
src=3D"http://www.codeproject.com/script/images/red.gif"=20
width=3D20 border=3D0></TD>
<TD><IMG height=3D5=20
=
src=3D"http://www.codeproject.com/script/images/red.gif"=20
width=3D20 border=3D0></TD>
<TD><IMG height=3D5=20
=
src=3D"http://www.codeproject.com/script/images/red.gif"=20
width=3D20 border=3D0></TD>
<TD><IMG height=3D5=20
=
src=3D"http://www.codeproject.com/script/images/red.gif"=20
width=3D20 border=3D0></TD>
<TD><IMG height=3D5=20
=
src=3D"http://www.codeproject.com/script/images/red.gif"=20
width=3D6 border=3D0><IMG height=3D5=20
=
src=3D"http://www.codeproject.com/script/images/white.gif"=20
width=3D14 =
border=3D0></TD></TR></TBODY></TABLE></TD></TR>
<TR>
<TD class=3DsmallText align=3Dright colSpan=3D2><A=20
title=3D"Calculated as rating x Log10(# votes)"=20
=
href=3D"http://www.codeproject.com/script/articles/top_articles.asp?st=3D=
2">Popularity:=20
5.6</A>. Rating: <B>4.31</B> out of=20
5.</TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE></TD></TR>
<TR>
<TD vAlign=3Dtop width=3D"100%">
<DIV id=3Dcontentdiv><!-- Article Starts -->
<UL class=3Ddownload>
<LI><A=20
=
href=3D"http://www.codeproject.com/atl/atl_underthehood_5/ATL_Under_The_H=
ood_Part_5_Src.zip">Download=20
source code - 3.8 Kb</A> </LI></UL><!-- Add the rest of your =
HTML here -->
<H2>Introduction</H2>
<P>Lots of people thing that ATL is made only for making COM =
components.=20
But in fact you can create full flash windows based application =
using ATL=20
by using the Windowing classes of ATL. Although you can convert =
your MFC=20
based project to ATL but there is very little support for UI =
component in=20
ATL, so you have to write lots of code yourself. For instance =
there is no=20
Document/View in ATL and if you want to make it then you have to =
implement=20
it yourself. In this part we are going to explore the windowing =
classes.=20
We also try to explore the techniques which ATL uses to do this. =
WTL=20
(Window Template Library), was untill now unsupported by Microsoft =
and is=20
in fact one step forward towards making graphical application. WTL =
is=20
based on ATL Windowing classes. </P>Before starting the discussion =
of any=20
ATL based program let's start our discussion with the classic =
Hello world=20
program. This program is completely written in SDK and almost all =
of us=20
are already familiar with it.=20
<P><B>Program 66</B> </P><PRE><SPAN =
class=3Dcpp-preprocessor>#include <windows.h></SPAN>
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM =
lParam);
<SPAN class=3Dcpp-keyword>int</SPAN> WINAPI WinMain(HINSTANCE hInstance, =
HINSTANCE hPrevInstance,=20
LPSTR lpCmdLine, <SPAN =
class=3Dcpp-keyword>int</SPAN> nCmdShow)
{
<SPAN class=3Dcpp-keyword>char</SPAN> szAppName[] =3D <SPAN =
class=3Dcpp-string>"Hello world"</SPAN>;
HWND hWnd;
MSG msg;
WNDCLASS wnd;
=20
wnd.cbClsExtra =3D NULL;
wnd.cbWndExtra =3D NULL;
wnd.hbrBackground =3D (HBRUSH)GetStockObject(WHITE_BRUSH);
wnd.hCursor =3D LoadCursor(NULL, IDC_ARROW);
wnd.hIcon =3D LoadIcon(NULL, IDI_APPLICATION);
wnd.hInstance =3D hInstance;
wnd.lpfnWndProc =3D WndProc;
wnd.lpszClassName =3D szAppName;
wnd.lpszMenuName =3D NULL;
wnd.style =3D CS_HREDRAW | CS_VREDRAW;
=20
<SPAN class=3Dcpp-keyword>if</SPAN> (!RegisterClass(&wnd))
{
MessageBox(NULL, <SPAN class=3Dcpp-string>"Can not register =
window class"</SPAN>, <SPAN class=3Dcpp-string>"Error"</SPAN>,=20
MB_OK | MB_ICONINFORMATION);
<SPAN class=3Dcpp-keyword>return</SPAN> -<SPAN =
class=3Dcpp-literal>1</SPAN>;
}
=20
hWnd =3D CreateWindow(szAppName, <SPAN class=3Dcpp-string>"Hello =
world"</SPAN>, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,=20
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, =
hInstance, NULL);
=20
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
=20
<SPAN class=3Dcpp-keyword>while</SPAN> (GetMessage(&msg, NULL, =
<SPAN class=3Dcpp-literal>0</SPAN>, <SPAN class=3Dcpp-literal>0</SPAN>))
{
DispatchMessage(&msg);
}
=20
<SPAN class=3Dcpp-keyword>return</SPAN> msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM =
lParam)
{
HDC hDC;
PAINTSTRUCT ps;
RECT rect;
<SPAN class=3Dcpp-keyword>switch</SPAN> (uMsg)
{
<SPAN class=3Dcpp-keyword>case</SPAN> WM_PAINT:
hDC =3D BeginPaint(hWnd, &ps);
GetClientRect(hWnd, &rect);
DrawText(hDC, <SPAN class=3Dcpp-string>"Hello world"</SPAN>, =
-<SPAN class=3Dcpp-literal>1</SPAN>, &rect, DT_SINGLELINE | =
DT_CENTER | DT_VCENTER);
EndPaint(hWnd, &ps);
<SPAN class=3Dcpp-keyword>break</SPAN>;
<SPAN class=3Dcpp-keyword>case</SPAN> WM_DESTROY:
PostQuitMessage(<SPAN class=3Dcpp-literal>0</SPAN>);
<SPAN class=3Dcpp-keyword>break</SPAN>;
}
=20
<SPAN class=3Dcpp-keyword>return</SPAN> DefWindowProc(hWnd, uMsg, =
wParam, lParam);
}
</PRE>
<P>There is nothing new in this program. This program just =
displays a=20
window and display Hello world at center of this. </P>ATL is =
object=20
oriented library, means you are using classes to do your work. =
Let's try=20
to do the same thing ourselves and make some small classes to make =
our=20
work easier. Ok we are going to make some classes for our work, =
but what=20
would be the criteria for making classes? In other words how many =
classes=20
are should make, what are their relationship, method and =
properties. I am=20
not planning to discuss the whole object oriented theory and the =
process=20
here to make quality library. To make my task similar I make group =
of=20
related API's and put those related API in one class. I put all =
the API's,=20
which deals with window in one class and it can be repeated to =
other type=20
of API's like for font, file, menu etc. So I made a small class =
and put=20
the entire API's whose first parameter is <CODE>HWND</CODE> in =
that class.=20
This class is nothing more than a thing wrapper on the Windows =
API's. My=20
class Name is <CODE>ZWindow</CODE>, you are free to choose =
whatever name=20
you like. This class is something like this. <PRE><SPAN =
class=3Dcpp-keyword>class</SPAN> ZWindow
{
<SPAN class=3Dcpp-keyword>public</SPAN>:
HWND m_hWnd;
ZWindow(HWND hWnd =3D <SPAN class=3Dcpp-literal>0</SPAN>) : =
m_hWnd(hWnd) { }
<SPAN class=3Dcpp-keyword>inline</SPAN> <SPAN =
class=3Dcpp-keyword>void</SPAN> Attach(HWND hWnd)
{ m_hWnd =3D hWnd; }
<SPAN class=3Dcpp-keyword>inline</SPAN> BOOL ShowWindow(<SPAN =
class=3Dcpp-keyword>int</SPAN> nCmdShow)
{ <SPAN class=3Dcpp-keyword>return</SPAN> ::ShowWindow(m_hWnd, =
nCmdShow); }
<SPAN class=3Dcpp-keyword>inline</SPAN> BOOL UpdateWindow()
{ <SPAN class=3Dcpp-keyword>return</SPAN> ::UpdateWindow(m_hWnd); }
};
</PRE>
<P>Here I put only those API's which are required at the moment. =
You may=20
add all the API's in this class. The only advantage of this class =
is that=20
now you don't have to pass the <CODE>HWND</CODE> parameter for =
windowing=20
API's, this class will pass that parameter itself. </P>
<P>Well nothing special till now. But what about our Window =
CallBack=20
function? Remember the first parameter of that call back function =
is also=20
<CODE>HWND</CODE>, so it should be member of this class according =
to our=20
criteria. So I add our callback function in this class too. Now =
this class=20
should be something like this. </P><PRE><SPAN =
class=3Dcpp-keyword>class</SPAN> ZWindow
{
<SPAN class=3Dcpp-keyword>public</SPAN>:
HWND m_hWnd;
ZWindow(HWND hWnd =3D <SPAN class=3Dcpp-literal>0</SPAN>) : =
m_hWnd(hWnd) { }
<SPAN class=3Dcpp-keyword>inline</SPAN> <SPAN =
class=3Dcpp-keyword>void</SPAN> Attach(HWND hWnd)
{ m_hWnd =3D hWnd; }
<SPAN class=3Dcpp-keyword>inline</SPAN> BOOL ShowWindow(<SPAN =
class=3Dcpp-keyword>int</SPAN> nCmdShow)
{ <SPAN class=3Dcpp-keyword>return</SPAN> ::ShowWindow(m_hWnd, =
nCmdShow); }
<SPAN class=3Dcpp-keyword>inline</SPAN> BOOL UpdateWindow()
{ <SPAN class=3Dcpp-keyword>return</SPAN> ::UpdateWindow(m_hWnd); }
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM =
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -