Win32学习笔记 第三章 HelloWin

Win32学习笔记

作者: 姜学哲([email protected])

教材: Windows程序设计(第五版)北京大学出版社
 [美]Charles Petzold 著
 北京博彦科技发展有限公司 译  ¥:160
参考资料:
 Windows 应用程序设计原理_方法_技术(因为是PDF格式的EBOOK,作者等不详)
 新编Windows API 参考大全  电子工业出版社  ¥:98
 C++ Primer(第三版)中国电力出版社 Stanley B.Lippman & Josee Lajoie 著 潘爱民 张丽 译 ¥:128
 TURBO C实用大全 徐金梧 杨德斌 徐科 编 ¥:42

环境: windows2000 Pro + Internet Explorer 6.0 + DirectX8.1 + Visual C++ 6.0

图们江计算机程序编制小组(http://chulsoft.xiloo.com)版权所有,转载请说明出处
--------------------------------------------------------------------
【第三章 HelloWin】

4月16日是值得纪念的日子。主页上传第十六天,我们的网站访问量是19500。我们什么都没有做,连搜索引擎都没有提交。所以感到很意外。怎么会有这么多人访问的,访客是怎么知道我们的网站的呢?真是匪夷所思。

经过了前两章的准备活动后要正式看WIN32代码了。在这之前我假设您已经具有C语言的知识。如果您没有C方面的知识,那么抓紧时间学吧。第三章的重点就是第三十九页开始的HelloWin了。我们的全部任务就是看懂它。可能是我特别低能+没耐心,几个月前第一次看到第三章的时候我选择了放弃,那时候觉得我这辈子都看不懂它,真是惭愧。

对我来讲它实在是太难了。因为很多新知识点对我来讲都是空白。头脑中一点概念都没有,真的是十足的“一头雾水”。因为感到WIN32太难,我又转向了DOS下的C,也就是TC2环境下的编程,学了一会儿,又觉得TC2也很难,又回到了WIN32,我也知道这种学习态度是不好的,虽然我这次从TC2转到WIN32的原因又是避重就轻,但是这次一定要学好WIN32,这再也不能像前几次那样了。

其实现在想起来,我缺的就是耐心,如果当时多看几遍就能看懂的,白白浪费了那么多时间。所以,如果您觉得这个程序太难,您一定要坚持多读几遍。过程是比较枯燥的。从一开始您就会碰到一些困难,比如Win32专用的术语。有些术语的含义简单,却很不好解释。

我们需要一段时间来适应。开头处您会碰到“窗口过程”,“窗口类”等术语。因为头脑中完全没有概念,所以当您看到这些术语的时候可能产生对人生的绝望。请珍稀您的生命,坚强一点,对付这些术语的方法是硬着头皮往下读。可以先不管具体的意思。只要在脑子里留点印象就可以了。等您看懂了HelloWin代码后再回过头来重读 N 遍,您会有意外的收获。

我是农民出身嘛!再加上智商也不是很高,读书只能用这种笨办法了。这种事要靠天份的。可能您看一遍就懂了也说不定。

当您读完了第三章后可能还有很多疑点。其中的相当一部分将在第四章中解释。所以当您看到了一个疑点,书中又没有详细说明时可以先跳过那段。学过后面几章后再回过头来看一看。这样做绝对不是浪费时间。

为了学好WIN32我曾经想过放弃"帝国时代"和"星际争霸",不不!!我死也不放弃!!我的最爱啊!可能随着学习的深入这些游戏会渐渐离我远去。对了,不知道星际什么时候出2代啊?

在前两章示例程序使用了MessageBox()来向用户输出文本。MessageBox()函数创建一个消息框窗口。在Windows中"窗口"一词有确切的含义。一个窗口就是屏幕上的一个矩形区域。它接收用户的输入,并以文本或图形的格式显示输出内容。

MessageBox()创建一个消息框窗口,但这只是一个功能有限的特殊窗口。这个窗口有一个带关闭按钮的标题栏、一个可选的图标、一行或多行文本,以及最多4个按钮。

MessageBox()虽然有用,但我们不能在消息框中显示图形,也不能在消息框中添加菜单。想要添加这些东东就需要创建自己的窗口,现在就开始。

书上说创建窗口很简单,只需要调用CreateWindow()即可。实际上Windows已经做好了大部分事情,我们所要做的只是记住API函数的名字和功能,然后到了实际的开发过程中照搬就可以了。这听起来似乎很简单,但是事实上还有很多工作需要程序员来做。

零件虽然做好了,但是组装起来还是得费一番功夫的。另外如果您的英语水平过得去,将对学习有很大的帮助。微软的MSDN是很好的东东。可惜我不会看啊。

进行Windows程序设计,实际上是进行一种面向对象的程序设计(OOP)。不要跟我说C不支持面向对象,我什么都不知道。

桌面上最明显的窗口就是应用程序窗口。这些窗口含有显示程序名称的标题栏,菜单,工具栏,滚动条。装饰对话框表面的还有各式各样的按钮,单选框,复选框,列表框,滚动条和文本输入区域。这些都是窗口。更确切地说这些都称为"子窗口","控件窗口","子窗口控件"。

其实按钮也是一种窗口。比如Windows的“开始”菜单按钮,它就是一个窗口,叫做“按钮窗口”。如果在不使用Windows API的情况下以C语言编写滚动条最快也得两个星期,而且写出来的滚动条一定是很难看的那种。对于像我们这样的菜鸟来说自己写滚动条函数并不是令人Happy的事情。非常Lucky的是Windows已经提供了一大串现成的滚动条函数。

当我们移动鼠标的时候,当我们敲键盘的时候,当我们单击鼠标左右键的时候…当…当…当…,会产生一种信号。这种信号代表某种操作。我们可以用一种信号表示鼠标的移动,用另一种信号表示鼠标左键的按下等等等等。Windows把这种信号称为“消息”。

当用户点击一个窗口时这个窗口就会收到一个“消息”。窗口以“消息”形式接收窗口的输入,窗口也用消息与其它窗口通讯。对于消息的理解将是学习编写Windows程序必须逾越的障碍之一。很重要啊!虽然消息这个东东并不是很难理解,但是确实是很陌生的东东。

按一个键盘会产生一个消息,移动鼠标产生一个消息,点击鼠标左键产生消息……总之Windows是靠消息来驱动的。到底什么是消息呢?等您看懂HelloWin程序之后大概也会明白。我只能说,多看几遍吧!!

我们可以用鼠标拖动窗口边框来改变窗口大小。程序会改变窗口中的内容来响应这种变化。重新调整窗口尺寸的工作是Windows处理的。应用程序没有这种负担。应用程序所要做的只是改变窗口的内容来响应这种变化。

应用程序是如何知道用户改变了窗口的尺寸的呢?有很多程序员已经习惯了字符模式程序。在字符模式下操作系统没有将此类消息通知给应用程序的机制。问题的关键在于理解Windows使用的体系结构。当用户改变窗口尺寸时Windows给程序发送一条消息,指出窗口的新尺寸。然后程序调整窗口中的内容,以反映尺寸的变化。

“Windows给程序发送消息”。这对于有过字符模式下编程经验的一些人来说有点不好理解。操作系统怎么会给程序发送消息呢?其实“Windows给程序发送消息”是指Windows调用程序中的一个函数,该函数的参数被设计为接收Windows和用户发出的消息。这种位于应用程序中的,被系统调用的函数被称为“窗口过程”。

我们对于应用程序调用操作系统是很好理解的。比如说在DOS下应用程序经常调用DOS中断。但是对于操作系统调用应用程序中的函数可能很不习惯。而这正是Windows面向对象体系结构的基础。

程序创建的每一个窗口都有一个相关的窗口过程。窗口过程是一个函数。这个函数可以在程序中,也可以在动态链接库中。Windows通过调用窗口过程来处理窗口发送的消息。窗口过程根据此消息进行处理,然后将控制返回给Windows。

窗口通常是在窗口类的基础上创建的。在阅读HelloWin的时候您会了解到什么是窗口类。窗口类中指定了处理该窗口的消息的窗口过程。多个窗口能够基于同一个窗口类,并且使用同一个窗口过程。例如,所有Windows程序中的所有按钮均基于同一个窗口类。我们所见过的所有的Windows按钮都使用一个窗口过程。

在窗口尺寸改变或窗口表面需要重画时由一种消息通知窗口。向窗口发送的消息由该窗口的窗口过程函数处理。

Windows程序开始执行后,Windows为该程序创建一个“消息队例”。这个消息队列用来存放该程序创建的各种不同的窗口消息。程序中有一小段代码,叫做“消息循环”,用来从队列中取出消息,并且将它们发送给相应的窗口过程。有些消息直接发送给窗口过程,不用放入消息队列中。

虽然我叽叽歪歪say了一堆,但是您可能还是不太明白。没关系,接下来我们看第一个Win32程序。这是本章的重点,而且是整个Win32的真正开始。这个代码具有代表性,您最好是手工敲几遍,这绝对有必要!这样脑子会留下一些印象。千万不要偷懒哦……

◎第三十九页:

/*------------------------------------------------------------
   HELLOWIN.C -- Displays "Hello, Windows 98!" in client area
                 (c) Charles Petzold, 1998
  ------------------------------------------------------------*/

#include <windows.h>

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    PSTR szCmdLine, int iCmdShow)
{
     static TCHAR szAppName[] = TEXT ("HelloWin") ;
     HWND         hwnd ;                //窗口句柄
     MSG          msg ;                 //消息结构
     WNDCLASS     wndclass ;            //窗口类结构

     wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
     wndclass.lpfnWndProc   = WndProc ;
     wndclass.cbClsExt

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是WIN API创建静态文本框并置于主窗口中央的代码: ```c++ #include <Windows.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { static TCHAR szAppName[] = TEXT("HelloWin"); 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 Windows NT!"), szAppName, MB_ICONERROR); return 0; } hwnd = CreateWindow(szAppName, TEXT("Hello, World!"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); // 创建静态文本框 HWND hStatic = CreateWindow(TEXT("STATIC"), TEXT("Hello, World!"), WS_CHILD | WS_VISIBLE | SS_CENTER, 0, 0, 0, 0, hwnd, NULL, hInstance, NULL); // 获取主窗口的客户区大小 RECT rect; GetClientRect(hwnd, &rect); // 获取静态文本框的大小 RECT staticRect; GetClientRect(hStatic, &staticRect); // 计算静态文本框的位置 int x = (rect.right - rect.left - staticRect.right + staticRect.left) / 2; int y = (rect.bottom - rect.top - staticRect.bottom + staticRect.top) / 2; // 移动静态文本框到主窗口中央 MoveWindow(hStatic, x, y, staticRect.right - staticRect.left, staticRect.bottom - staticRect.top, TRUE); ShowWindow(hwnd, iCmdShow); 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_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hwnd, message, wParam, lParam); } return 0; } ``` 在这个示例代码中,我们使用了`CreateWindow`函数创建了一个静态文本框,并使用`GetClientRect`函数和`MoveWindow`函数计算并移动了它的位置,使其置于主窗口的正中央。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值