当前位置:文档之家› 窗口和消息

窗口和消息

窗口和消息
窗口和消息

窗口和消息 壹佰软件开发小组 整理编窗口和消息

在前两章,程序使用了同一个函数MessageBox来向使用者输出文字。MessageBox 函数会建立一个「窗口」。在Windows中,「窗口」一词有确切的含义。一个窗口就是屏幕上的一个矩形区域,它接收使用者的输入并以文字或图形的格式显示输出内容。

MessageBox函数建立一个窗口,但这只是一个功能有限的特殊窗口。消息窗口有一个带关闭按钮的标题列、一个选项图标、一行或多行文字,以及最多四个按钮。当然,必须选择Windows提供给您的图标与按钮。

MessageBox函数非常有用,但下面不会过多地使用它。我们不能在消息框中显示图形,而且也不能在消息框中添加菜单。要添加这些对象,就需要建立自己的窗口,现在就开始。

自己的窗口

自己的窗口

建立窗口很简单,只需呼叫CreateWindow函数即可。

好啦,虽然建立窗口的函数的确名为CreateWindow,而且您也能在/Platform SDK/User Interface Services/Windowing/Windows/Window Reference/Window Functions找到此文件,但您将发现CreateWindow的第一个参数就是所谓的「窗口类别名称」,并且该窗口类别连接所谓的「窗口消息处理程序」。在我们呼叫CreateWindow之前,有一点背景知识会对您大有帮助。

总体结构

总体结构

进行Windows程序设计,实际上是在进行一种对象导向的程序设计(OOP)。这一点在Windows中使用得最多的对象上表现最为明显。这种对象正是Windows

之所以命名为「Windows」的原因,它具有人格化的特征,甚至可能会在您的梦中出现,这就是那个叫做「窗口」的东西。

桌面上最明显的窗口就是应用程序窗口。这些窗口含有显示程序名称的标题列、菜单甚至可能还有工具列和滚动条。另一类窗口是对话框,它可以有标题列也可以没有标题列。

装饰对话框表面的还有各式各样的按键、单选按钮、复选框、清单方块、滚动条和文字输入区域。其中每一个小的视觉对象都是一个窗口。更确切地说,这些都称为「子窗口」或「控件窗口」或「子窗口控件」。

作为对象,使用者会在屏幕上看到这些窗口,并通过键盘和鼠标直接与它们进行交互操作。更有趣的是,程序写作者的观点与使用者的观点极其类似。窗口以「消

息」的形式接收窗口的输入,窗口也用消息与其它窗口通讯。对讯息的理解将是学习如何写作Windows程序所必须越过的障碍之一。

这有一个Windows的消息范例:我们知道,大多数的Windows程序都有大小合适的应用程序窗口。也就是说,您能够通过鼠标拖动窗口的边框来改变窗口的大小。通常,程序将通过改变窗口中的内容来响应这种大小的变化。您可能会猜测(并且您也是正确的),是Windows本身而不是应用程序在处理与使用者重新调整窗口大小相关的全部杂乱程序。由于应用程序能改变其显示的样子,所以它也「知道」窗口大小改变了。

应用程序是如何知道使用者改变了窗口的大小的呢?由于程序写作者习惯了往常的文字模式程序,操作系统没有设置将此类消息通知给使用者的机制。问题的关键在于理解Windows所使用的架构。当使用者改变窗口的大小时,Window给程序发送一个消息指出新窗口的大小。然后程序就可以调整窗口中的内容,以响应大小的变化。

「Windows给程序发送消息。」我们希望读者不要对这句话视而不见。它到底表达了什么意思呢?我们在这里讨论的是程序代码,而不是一个电子邮件系统。操作系统怎么给程序发送消息呢?

其实,所谓「Windows给程序发送消息」,是指Windows呼叫程序中的一个函数,该函数的参数描述了这个特定消息。这种位于Windows程序中的函数称为「窗口消息处理程序」。

无疑,读者对程序呼叫操作系统的做法是很熟悉的。例如,程序在打开磁盘文件时就要使用有关的系统呼叫。读者所不习惯的,可能是操作系统呼叫程序,而这正是Windows对象导向架构的基础。

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

更确切地说,窗口通常是在「窗口类别」的基础上建立的。窗口类别标识了处理窗口消息的窗口消息处理程序。使用窗口类别使多个窗口能够属于同一个窗口类别,并使用同一个窗口消息处理程序。例如,所有Windows程序中的所有按钮均依据同一个窗口类别。这个窗口类别与一个处理所有按钮消息的窗口消息处理程序(位于Windows的动态链接库中)联结。

在对象导向的程序设计中,对象是程序与数据的组合。窗口是一种对象,其程序是窗口消息处理程序。数据是窗口消息处理程序保存的信息和Windows为每个窗口以及系统中那个窗口类别保存的信息。

窗口消息处理程序处理给窗口发送消息。这些消息经常是告知窗口,使用者正使用键盘或者鼠标进行输入。这正是按键窗口知道它被「按下」的奥妙所在。在窗口大小改变,或者窗口表面需要重画时,由其它消息通知窗口。

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

如果您对这段Windows架构过于简略的描述将信将疑,就让我们去看看在实际的程序中,窗口、窗口类别、窗口消息处理程序、消息队列、消息循环和窗口消息是如何相互配合的。这或许会对您有些帮助。

HELLOWIN程序

程序

建立一个窗口首先需要注册一个窗口类别,那需要一个窗口消息处理程序来处理窗口消息。处理窗口消息对每个Windows程序都带来了些负担。程序3-1所示的HELLOWIN程序中整个做的事情差不多就是料理这些事情。

程序3-1 HELLOWIN

HELLOWIN.C

/*------------------------------------------------------------------------

HELLOWIN.C -- Displays "Hello, Windows 98!" in client area

(c) Charles Petzold, 1998

-----------------------------------------------------------------------*/

#include

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 ;

WNDCLASwndclass ;

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.lpszMenuNam = NULL ;

wndclass.lpszClassName= szAppName ;

if (!RegisterClass (&wndclass))

{

MessageBox ( NULL, TEXT ("This program requires Windows NT!"),

szAppName, MB_ICONERROR) ;

return 0 ;

}

hwnd = CreateWindow( szAppName, // window class name

TEXT ("The Hello Program"), // window caption WS_OVERLAPPEDWINDOW, // window style

CW_USEDEFAULT,// initial x position

CW_USEDEFAULT,// initial y position

CW_USEDEFAULT,// initial x size

CW_USEDEFAULT,// initial y size

NULL, // parent window handle NULL, // window menu handle

hInstance, // program instance handle

NULL) ; // creation parameters

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)

{

HDC hdc ;

PAINTSTRUCT ps ;

RECT rect ;

switch (message)

{

case WM_CREATE:

PlaySound (TEXT ("hellowin.wav"), NULL, SND_FILENAME | SND_ASYNC) ;

return 0 ;

case WM_PAINT:

hdc = BeginPaint (hwnd, &ps) ;

GetClientRect (hwnd, &rect) ;

DrawText (hdc, TEXT ("Hello, Windows 98!"), -1, &rect,

DT_SINGLELINE | DT_CENTER | DT_VCENTER) ;

EndPaint (hwnd, &ps) ;

return 0 ;

case WM_DESTROY:

PostQuitMessage (0) ;

return 0 ;

}

return DefWindowProc (hwnd, message, wParam, lParam) ;

}

程序建立一个普通的应用程序窗口,如图3-1所示。在窗口显示区域的中央显示「Hello, Windows 98!」。如果安装了声卡,那么您还可以听到相应的朗读声音。

图3-1 HELLOWIN 窗口

提醒您注意:如果您使用Microsoft Visual C++ 为此程序建立新项目,那么您

得加上连结程序所需的链接库文件。从Project菜单选择 Setting选项,然后

General

ral,然后在

选取Link页面标签。从 Category清单方块中选择Gene

ral

Windows multimedia-

WINMM.LIB(Windows multimedia Object/Library Modules文字方块添加WINMM.LIB

Windows multimedia

多媒体)。您这样做是因为HELLOWIN将使用多媒体功能呼叫,而内定Windows多媒体

的项目中又不包括多媒体链接库文件。不然连结程序报告了错误信息,表明

PlaySound函数不可用。

HELLOWIN将存取文件HELLOWIN.WAV,该文件在本书所附光盘的HELLOWIN目录中。

执行HELLOWIN.EXE时,内定的目录必须是HELLOWIN。在Visual C++中执行此程

序时,虽然执行文件会产生在HELLOWIN的RELEASE或DEBUG子目录中,但执行

程序的目录还是必须在HELLOWIN中。

通盘考量

通盘考量

实际上,每一个Windows程序代码中都包括HELLOWIN.C程序的大部分。没人能

真正记住此程序的全部写法;通常,Windows程序写作者在开始写一个新程序时

总是会复制一个现有的程序,然后再做相应的修改。您可以按此习惯自由使用本

书附带光盘中的程序。

上面提到,HELLOWIN将在其窗口的中央显示字符串。这种说法不是完全正确的。

文字实际显示在程序显示区域的中央,它在图3-1中是标题列和边界范围内的大

片白色区域。这区别对我们来说很重要;显示区域就是程序自由绘图并且向使用

者显示输出结果的窗口区域。

如果您认真思考一下,将会发现虽然只有80行程序代码,这个窗口却令人惊讶

地具有许多功能。您可以用鼠标按住标题列,在屏幕上移动窗口;可以按住大小

边框,改变窗口的大小。在窗口大小改变时,程序自动地将「Hello, Windows 98!」

字符串重新定位在显示区域的中央。您可以按最大化按钮,放大HELLOWIN以充

满整个屏幕;也可以按最小化按钮,将程序缩小成一个图示。您可以在系统菜单

中执行所有选项(就是按下在标题列最左端的小图示);也可以从系统菜单中选

择 Close选项,或者单击标题列最右端的关闭按钮,或者双击标题列最左端的

图标,来关闭窗口以终止程序的执行。

我们将在本章的余下部分对此程序作一详细的检查。当然,我们首先要从整体上

看一下。

与前两章中的范例程序一样,HELLOWIN.C也有一个WinMain函数,但它还有另

外一个函数,名为WndProc。这就是窗口消息处理程序。注意,在HELLOWIN.C

中没有呼叫WndProc的程序代码。当然,在WinMain中有对WndProc的参考,而

这就是该函数要在程序开头附近声明的原因。

函数呼叫

Windows函数呼叫

HELLOWIN至少呼叫了18个Windows函数。下面以它们在HELLOWIN中出现的次序列出这些函数以及各自的简明描述:

?LoadIcon 加载图标供程序使用。

?LoadCursor 加载鼠标光标供程序使用。

?GetStockObject 取得一个图形对象(在这个例子中,是取得绘制窗口背景的画刷对象)。

?RegisterClass 为程序窗口注册窗口类别。

?MessageBox 显示消息框。

?CreateWindow 根据窗口类别建立一个窗口。

?ShowWindow 在屏幕上显示窗口。

?UpdateWindow 指示窗口自我更新。

?GetMessage 从消息队列中取得消息。

?TranslateMessage 转译某些键盘消息。

?DispatchMessage 将消息发送给窗口消息处理程序。

?PlaySound 播放一个声音文件。

?BeginPaint 开始绘制窗口。

?GetClientRect 取得窗口显示区域的大小。

?DrawText 显示字符串。

?EndPaint 结束绘制窗口。

?PostQuitMessage 在消息队列中插入一个「退出程序」消息。

?DefWindowProc 执行内定的消息处理。

这些函数均在Platform SDK文件中说明,并在不同的表头文件中声明,其中绝大多数声明在WINUSER.H中。

大写字母标识符

大写字母标识符

读者可能注意到,HELLOWIN.C中有几个大写的标识符,这些标识符是在Windows 表头文件中定义的。有些标识符含有两个字母或者三个字母的前缀,这些前缀后头接着一个底线:

这些是简单的数值常数。前缀指示该常数所属的类别,如表3-1所示。

表3-1

类别

前缀类别

CS 窗口类别样式

CW 建立窗口

DT 绘制文字

IDI 图示ID

IDC 游标ID

MB 消息框

SND 声音

WM 窗口消息

WS 窗口样式

奉劝程序写作者不要费力气去记忆Windows程序设计中的数值常数。实际上,Windows中使用的每个数值常数在表头文件中均有相应的标识符定义。

新的数据型态

新的数据型态

HELLOWIN.C中的其它标识符是新的数据型态,也在Windows表头文件中使用typedef叙述或者#define叙述加以定义了。最初是为了便于将Windows程序从原来的16位系统上移植到未来的使用32位(或者其它)技术的操作系统上。这种作法并不如当时每个人想象的那样顺利,但是这种概念基本上是正确的。

有时这些新的数据型态只是为了方便缩写。例如,用于WndProc 的第二个参数的UINT 数据型态只是一个unsigned int (无正负号整数),在Windows 98中,这是一个32位的值。用于WinMain 的第三个参数的PSTR 数据型态是指向一个字符串的指针,即是一个char *。

其它数据型态的含义不太明显。例如,WndProc 的第三和第四个参数分别被定义为WPARAM 和LPARAM,这些名字的来源有点历史背景:当Windows 还是16位系统时,WndProc 的第三个参数被定义为一个WORD,这是一个16位的 无正负号短(unsigned short)整数,而第四个参数被定义为一个LONG,这是一个32位有正负号长整数,从而导致了文字「PARAM」前面加上了前置前缀「W」和「L」。当然,在32位的Windows 中,WPARAM 被定义为一个UINT,而LPARAM 被定义为一个LONG(这就是C 中的long 整数型态),因此窗口消息处理程序的这两个参数都是32位的值。这也许有点奇怪,因为WORD 数据型态在Windows98中仍然被定义为一种16位的 无正负号

无正负号整数,因此「PARAM」前的「W」就有点误用了。 WndProc 函数传回一个型态为LRESULT 的值,该值简单地被定义为一个LONG。WinMain 函数被指定了一个WINAPI 型态(在表头文件中定义的所有Windows 函数都被指定这种型态),而WndProc 函数被指定一个CALLBACK 型态。这两个标识符都被定义为_stdcall,表示在Windows 本身和使用者的应用程序之间发生的函数呼叫的呼叫参数传递方式。

HELLOWIN 还使用了Windows 表头文件中定义的四种数据结构(我们将在本章稍后加以讨论)。这些数据结构如表3-2所示。

表3-2结构

结构 含义含义 MSG

消息结构 WNDCLASS

窗口类别结构PAINTSTRUCT 绘图结构

RECT 矩形结构 前面两个数据结构在WinMain 中使用,分别定义了两个名为msg 和wndclass 的结构,后面两个数据结构在WndProc 中使用,分别定义了ps 和rect 结构。 句柄简介

句柄简介 最后,还有三个大写标识符(见表3-3),用于不同型态的「句柄」:

表3-3

标识符

标识符 含义含义 HINSTANCE 执行实体(程序自身)句柄

HWND

窗口句柄 HDC 设备内容句柄

句柄在Windows 中使用非常频繁。在本章结束之前,我们将遇到HICON(图标句柄)、HCURSOR(鼠标光标句柄)和HBRUSH(画刷句柄)。

句柄是一个(通常为32位的)整数,它代表一个对象。Windows 中的句柄类似传统C 或者MS-DOS 程序设计中使用的文件句柄。程序几乎总是通过呼叫Windows 函数取得句柄。程序在其它Windows 函数中使用这个句柄,以使用它代表的对象。代号的实际值对程序来说是无关紧要的。但是,向您的程序提供代号的Windows 模块知道如何利用它来使用相对应的对象。

匈牙利表示法

匈牙利表示法 读者可能注意到,HELLOWIN.C 中有一些变量的名字显得很古怪。如szCmdLine,它是传递给WinMain 的参数。

许多Windows 程序写作者使用一种叫做「匈牙利表示法」的变量命名通则。这是为了纪念传奇性的Microsoft 程序写作者Charles Simonyi。非常简单,变量名以一个或者多个小写字母开始,这些字母表示变量的数据型态。例如,szCmdLine 中的sz 代表「以0结尾的字符串」。在hInstance 和hPrevInstance 中的h 前缀表示「句柄」;在iCmdShow 中的i 前缀表示「整数」。WndProc 的后两个参数也使用匈牙利表示法。正如我在前面已经解释过的,尽管wParam 应该更适当地被命名为uiParam(代表「无正负号整数」),但是因为这两个参数是使用数据型态WPARAM 和LPARAM 定义的,因此保留它们传统的名字。

在命名结构变量时,可以用结构名(或者结构名的一种缩写)的小写作为变量名的前缀,或者用作整个变量名。例如,在HELLOWIN. C 的WinMain 函数中,msg 变量是MSG 型态的结构;wndclass 是WNDCLASSEX 型态的一个结构。在WndPmc 函数中,ps 是一个PAINTSTRUCT 结构,rect 是一个RECT 结构。

匈牙利表示法能够帮助程序写作者及早发现并避免程序中的错误。由于变量名既描述了变量的作用,又描述了其数据型态,就比较容易避免产生数据型态不合的错误。

表3-4列出了在本书中经常用到的变量前缀。

表3-4前缀

前缀 数据型态数据型态 c

char 或WCHAR 或TCHAR by

BYTE (无正负号字符) n

short i int

x, y int 分别用作x 坐标和y 坐标

cx, cy int 分别用作x 长度和y 长度;C 代表「计数器」

b 或f BOOL (int);f 代表「旗标」

w WORD (无正负号短整数)

l LONG (长整数)

dw DWORD (无正负号长整数)

fn function(函数)

s string(字符串)

sz 以字节值0结尾的字符串

h 句柄

p 指标

注册窗口类别

注册窗口类别

窗口依照某一窗口类别建立,窗口类别用以标识处理窗口消息的窗口消息处理程序。

不同窗口可以依照同一种窗口类别建立。例如,Windows中的所有按钮窗口-包括按键、复选框,以及单选按钮-都是依据同一种窗口类别建立的。窗口类别定义了窗口消息处理程序和依据此类别建立的窗口的其它特征。在建立窗口时,要定义一些该窗口所独有的特征。

在为程序建立窗口之前,必须首先呼叫RegisterClass注册一个窗口类别。该函数只需要一个参数,即一个指向型态为WNDCLASS的结构指针。此结构包括两个指向字符串的字段,因此结构在WINUSER.H表头文件中定义了两种不同的方式,第一个是ASCII版的WNDCLASSA:

typedef struct tagWNDCLASSA

{

UINT style ;

WNDPROC lpfnWndProc ;

int cbClsExtra ;

int cbWndExtra ;

HINSTANCE hInstance ;

HICON hIcon ;

HCURSOR hCursor ;

HBRUSH hbrBackground ;

LPCSTR lpszMenuName ;

LPCSTR lpszClassName ;

}

WNDCLASSA, * PWNDCLASSA, NEAR * NPWNDCLASSA, FAR * LPWNDCLASSA ;

在这里提示一下数据型态和匈牙利表示法:其中的lpfn前缀代表「指向函数的长指标」。(在Win32 API中,长指标和短指标(或者近程指标)没有区别。这只是16位Windows的遗物。)cb前缀代表「字节数」而且通常作为一个常数来表示一个字节的大小。h前缀是一个句柄,而hbr前缀代表「一个画刷的代号」。lpsz前缀代表「指向以0结尾字符串的指针」。

Unicode版的结构定义如下:

typedef struct tagWNDCLASSW

{

UINT style ;

WNDPROC lpfnWndProc ;

int cbClsExtra ;

int cbWndExtra ;

HINSTANCE hInstance ;

HICON hIcon ;

HCURSOR hCursor ;

HBRUSH hbrBackground ;

LPCWSTR lpszMenuName ;

LPCWSTR lpszClassName ;

}

WNDCLASSW, * PWNDCLASSW, NEAR * NPWNDCLASSW, FAR * LPWNDCLASSW ;

与前者唯一的区别在于最后两个字段定义为指向宽字符串常数,而不是指向ASCII字符串常数。

WINUSER.H定义了WNDCLASSA和WNDCLASSW结构(以及指向结构的指针)以后,表头文件依据对UNICODE标识符的解释,定义了WNDCLASS和指向WNDCLASS的指标(包括一些向后兼容的程序代码):

#ifdef UNICODE

typedef WNDCLASSW WNDCLASS ;

typedef PWNDCLASSW PWNDCLASS ;

typedef NPWNDCLASSW NPWNDCLASS ;

typedef LPWNDCLASSW LPWNDCLASS ;

#else

typedef WNDCLASSA WNDCLASS ;

typedef PWNDCLASSA PWNDCLASS ;

typedef NPWNDCLASSA NPWNDCLASS ;

typedef LPWNDCLASSA LPWNDCLASS ;

#endif

本书后面列出结构时,将只列出功用相同的结构定义,对WNDCLASS就像这样:

typedef struct

{

UINT style ;

WNDPROC lpfnWndProc ;

int cbClsExtra ;

int cbWndExtra ;

HINSTANCE hInstance ;

HICON hIcon ;

HCURSOR hCursor ;

HBRUSH hbrBackground ;

LPCTSTR lpszMenuName ;

LPCTSTR lpszClassName ;

}

WNDCLASS, * PWNDCLASS ;

我也不再着重说明指标的定义。一个程序写作者的程序不应该因为使用以LP或NP为前缀的不同指针型态而被搅乱。

在WinMain中为WNDCLASS定义一个结构,通常像这样:

WNDCLASS wndclass ;

然后,你就可以初始化该结构的10个字段,并呼叫RegisterClass。

在WNDCLASS结构中最重要的两个字段是第二个和最后一个,第二个字段(lpfnWndProc) 是依据这个类别来建立的所有窗口所使用的窗口消息处理程序的地址。在HELLOWIN.C中,这个是WndProc函数。最后一个字段是窗口类别的文字名称。程序写作者可以随意定义其名称。在只建立一个窗口的程序中,窗口类别名称通常设定为程序名称。

其它字段依照下面的方法描述了窗口类别的一些特征。让我们依次看看WNDCLASS结构中的每个字段。

叙述

wndclass.style = CS_HREDRAW | CS_VREDRAW ;

使用C的位「或」运算子结合了两个「窗口类别样式」标识符。在表头文件WINUSER.H中,已定义了一整组以CS为前缀的标识符:

#define CS_VREDRAW 0x0001

#define CS_HREDRAW 0x0002

#define CS_KEYCVTWINDOW 0x0004

#define CS_DBLCLKS 0x0008

#define CS_OWNDC 0x0020

#define CS_CLASSDC 0x0040

#define CS_PARENTDC 0x0080

#define CS_NOKEYCVT 0x0100

#define CS_NOCLOSE 0x0200

#define CS_SAVEBITS 0x0800

#define CS_BYTEALIGNCLIENT 0x1000

#define CS_BYTEALIGNWINDOW 0x2000

#define CS_GLOBALCLASS 0x4000

#define CS_IME 0x00010000

由于每个标识符都可以在一个复合值中设置一个位的值,所以按这种方式定义的标识符通常称为「位旗标」。通常我们只使用少数的窗口类别样式。HELLOWIN 中用到的这两个标识符表示,所有依据此类别建立的窗口,每当窗口的水平方向大小(CS_HREDRAW)或者垂直方向大小(CS_VREDRAW)改变之后,窗口要完全重画。改变HELLOWIN的窗口大小,可以看到字符串仍然显示在窗口的中央,这两个标识符确保了这一点。不久我们就将看到窗口消息处理程序是如何得知这种窗口大小的变化的。

WNDCLASS结构的第二个字段由以下叙述进行初始化:

wndclass.lpfnWndProc = WndProc ;

这条叙述将这个窗口类别的窗口消息处理程序设定为WndProc,即HELLOWIN.C 中的第二个函数。这个过程将处理依据这个窗口类别建立的所有窗口的全部消息。在C语言中,像这样在结构中使用函数名时,真正提供的是指向函数的指标。

下面两个字段用于在窗口类别结构和Windows内部保存的窗口结构中预留一些额外空间:

wndclass.cbClsExtra = 0 ;

wndclass.cbWndExtra = 0 ;

程序可以根据需要来使用预留的空间。HELLOWIN没有使用它们,所以设定值为0。否则,和匈牙利表示法所指示的一样,这个字段将被当成「预留的字节数」。(在第七章的程序CHECKER3将使用cbWndExtra字段。)

下一个字段就是程序的执行实体句柄(它也是WinMain的参数之一):

wndclass.hInstance = hInstance ;

叙述

wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;

为所有依据这个窗口类别建立的窗口设置一个图标。图标是一个小的位图图像,它对使用者代表程序,将出现在Windows工作列中和窗口的标题列的左端。在本书的后面,您将学习如何为您的Windows程序自订图标。现在,为了方便起见,我们将使用预先定义的图示。

要取得预先定义图示的句柄,可以将第一个参数设定为NULL来呼叫LoadIcon。在加载程序写作者自订的图标时(图标应该存放在磁盘上的.EXE程序文件中),这个参数应该被设定为程序的执行实体句柄hInstance。第二个参数代表图示。对于预先定义图示,此参数是以IDI开始的标识符(「ID代表图示」),标识符在WINUSER.H中定义。IDI_APPLICATION图标是一个简单的窗口小图形。LoadIcon函数传回该图示的句柄。我们并不关心这个句柄的实际值,它只用于设置hIcon字段元的值。该字段在WNDCLASS结构中定义为HICON型态,此型态名的含义为「handle to an icon(图示句柄)」。

叙述

wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;

与前一条叙述非常相似。LoadCursor函数加载一个预先定义的鼠标光标(命名为IDC_ARROW),并传回该游标的句柄。该句柄被设定给WNDCLASS结构的hCursor 字段。当鼠标光标在依据这个类别建立的窗口的显示区域上出现时,它变成一个小箭头。

下一个字段指定依据这个类别建立的窗口背景颜色。hbrBackground字段名称中的hbr前缀代表「handle to a brush(画刷句柄)」。画刷是个绘图词汇,指用来填充一个区域的着色样式。Windows有几个标准画刷,也称为「备用(stock)」画刷。这里所示的GetStockObject呼叫将传回一个白色画刷的句柄:

wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;

这意味着窗口显示区域的背景完全为白色,这是一种极其普遍的做法。

下一个字段指定窗口类别菜单。HElLOWIN没有应用程序菜单,所以该字段被设定为NULL:

wndclass.lpszMenuName = NULL ;

最后,必须给出一个类别名称。对于小程序,类别名称可以与程序名相同,即存放在szAppName变量中的「HelloWin」字符串。

wndclass.lpszClassName = szAppName ;

至于该字符串由ASCII字符组成或由Unicode字符组成,取决于是否定义了UNICODE标识符。

在初始化该结构的10个字段后,HELLOWIN呼叫RegisterClass来注册这个窗口类别。该函数只有一个参数,即指向WNDCLASS结构的指针。实际上,RegisterClassA函数将获得一个指向WNDCLASSA结构的指针,而RegisterClassW 函数将获得一个指向WNDCLASSW结构的指针。程序要使用哪个函数来注册窗口类别,取决于发送给窗口的消息包含ASCII文字还是Unicode文字。

现在有一个问题:如果用定义的UNICODE标识符编译了程序,程序将呼叫RegisterClassW。该程序可以在Microsoft Windows NT中执行良好。但如果此程序在Windows 98上执行,RegisterClassW函数并未真地被执行到。函数有一个进入点,但函数呼叫后只传回0,表明错误。对于在Windows 98下执行的Unicode程序来说,这是一个通知使用者有问题并终止执行的好机会。这是本书中多数程序处理RegisterClass函数呼叫的方法:

if (!RegisterClass (&wndclass))

{

MessageBox ( NULL, TEXT ("This program requires Windows NT!"), szAppName, MB_ICONERROR) ;

return 0 ;

}

由于MessageBoxW是可在Windows 98环境下执行的几个Unicode函数之一,所以其执行正常。

当然,这段程序假定RegisterClass不会因为其它原因而呼叫失败,诸如WNDCLASS结构中lpfnWndProc字段被设定成NULL之类的错误。GetLastError 函数会帮助您确定在这样的情况下产生错误的原因。GetLastError是Windows 中常用的函数,它可以在函数呼叫失败时获得更多错误信息。不同函数的文件将指出您是否能够用GetLastError来获得这些信息。在Windows 98中呼叫RegisterClassW时,GetLastError将传回120。在WINERROR.H中您可以看到,值120与标识符ERROR_CALL_NOT_IMPLEMENTED相等。您也可以在/Platform SDK/Windows Base Services/Debugging and Error Handling/Error

Codes/System Errors - Numerical Order查看错误。

一些Windows程序写作者喜欢检查所有可能发生错误的函数呼叫的传回值。这么做确实有点道理,相信您也非常习惯在配置内存后检查错误。而许多Windows 函数需要配置内存。例如,RegisterClass需要配置内存,以保存窗口类别的信息。如此一来,您就应该要检查这个函数的执行结果。另一方面说来,如果由于RegisterClass不能得到所需要的内存,它会声明呼叫失败,而Windows大概也快当掉了。

在本书的范例程序中,我做了最少的错误检查。这不是因为我认为错误检查不是一个好方法,而是因为这会让我们在程序举例中分心。

最后,一个老经验是:在一些Windows范例程序中,您可能在WinMain中看到以下程序代码:

if (!hPrevInstance)

{

wndclass.cbStyle = CS_HREDRAW | CS_VREDRAW ;

初始化其它 wndclass

RegisterClass (&wndclass) ;

}

理解窗口与消息

4.1.1窗口是什么 窗口是什么?大家每天在使用Windows,屏幕上的一个个方块就是一个个窗口!那么,窗口为什么是这个样子呢?窗口就是程序吗? 1. 使用窗口的原因(窗口是什么呢?看看自家阳台上的窗口就知道了。windows 操作系统里的窗口就是从那里延伸过来的,要理解也不是那么难的。)回想一下DOS时代的计算机屏幕,在1990年Windows 3.0推出之前,计算机的屏幕一直使用文本模式,黑洞洞的底色上漂浮着白色的小字,性能不高的图形模式只用于游戏和一些图形软件。对DOS程序来说,屏幕是惟一的,上面有个光标表示输入字符的位置,程序运行后往屏幕输出一些信息,退出时输出的信息就留在了屏幕上,然后是第二个程序重复这个过程,当屏幕被写满的时候,整个屏幕上卷一行,最上面一行被去掉,然后程序在最底下新空出来的一行上继续输出。(作者讲这些话时我想应该是假设初学者连什么是DOS程序都不会的,要是那样的话,看这本书是铁定看不懂的。作者很留恋那个幸福的DOS时代吧。)对于一个单任务的操作系统,这种方式是很合理的,因为平时使用传真机或打字机就是用上卷的方式来容纳新的内容的。但是如果是多任务呢?两个程序同时往屏幕上写东西或者两个人同时往打字机上打字,那么谁都看不懂混在一起的是什么。DOS下的TSR(内存驻留)程序是多个程序同时使用一个屏幕的例子,但实质上这并不是多任务,而是TSR将别的程序暂时挂起,挂起的程序不可能在TSR执行期间再向屏幕输出内容,TSR在输出自己的内容之前必须保存屏幕上显示的内容,并在退出的时候把屏幕恢复原来的样子,否则挂起的程序并不知道屏幕已经被改变,在这个过程中,DOS不会去干预中间发生的一切。(这里有一句话不甚理解,TSR会输出自己的内容吗?为什么?后面的在TSR输出前将屏幕保存起来,和在使用后将屏幕恢复成原来的样子,这个倒不难理解。关键是什么是内存驻留程序?它和一般的程序有什么区别?) Windows是多任务的操作系统,可以同时运行多个程序,同样,各个程序在屏幕上的显示不能互相干扰,而且,多个程序可以看成是“同时”运行的,在后台的程序也可能随时向屏幕输出内容,这中间的调度是由Windows完成的。Windows采用的方法是给程序一块矩形的屏幕空间,这就是窗口。应用程序通过Windows向属于自己的窗口显示信息,Windows判断该窗口是不是被别的窗口挡住,并把没有挡住的部分输出到屏幕上,这样屏幕上显示的东西就不会互相覆盖而乱套。对于应用程序来说,它只需认为窗口就是自己拥有的显示空间就可以了。(这一段话极其重要,尤其是显示为紫色的一段文字,更是重要的没法讲。它是那么的简约而不简单啊,向我们展示了WINDOWS操作系统的一个深层面的运行原理,而又是其一个非常重要的原理。) 2. 窗口和程序的关系 既然不同窗口的内容就是不同程序的输出,那么一个窗口就是一个程序吗?反过来,一个程序就是一个窗口吗? 答案是否定的,一个窗口不一定就是一个程序,它可能只是一个程序的一部分。一个程序可以建立多个顶层窗口,如Windows的桌面和任务栏都是顶层窗口,但它们都属于“文件管理器”进程,所以并不是一个窗口就是一个程序的代表。Windows的窗口采用层次结构,一个窗口中可以建立多个子窗口,如窗口中的状态栏、工具栏,对话框中的按钮、文本输入框与复选框等都是子窗口。子窗口中还可以再建立下一级子窗口,如Word工具栏上的字体选择框。(这里的介绍非常

Windows消息分类

Windows消息分类 Windows应用程序都是基于消息驱动的,消息一般分为标准Windows消息、控件通知消息和命令消息三大类。 1. 标准Windows消息 标准Windows消息,除WM_COMMAND消息外,所有以WM为前缀的消息都是标准Windows消息。标准Windows消息只能由窗口类和视图类进行处理。标准Windows消息都有黙认的处理函数,这些函数在CWnd类中过行了预定义,处理函数均以前缀On开头。 标准Windows消息主要分为三类: (1)键盘消息 当用户按下键盘上的某一个键时,会产生WM_CHAR消息。该消息的处理函数为OnChar. (2) 鼠标消息 WM_MOUSEMOVE WM_LBUTTONDOWN WM_RBUTTONDOWN (3)窗口消息 所有窗口的变化,包括内容重绘、窗口最大化、窗口重新定义大小、窗口滚动条滚动等产生的消息均属于窗口消息。当调用成员函数UpdateWindow 或RedrawWindow要求重新绘制窗口内容时,将会发送WM_PAINT消息,当窗口最小化后再还原或被其它窗口遮盖后又移开时,也会发送WM_PAINT消息。WM_PAINT消息的处理函数为OnPaint. 2. 控件消息(WM_COMMAND) 由控件产生的消息,例如按钮,列表框的选择等都会产生通告消息。控件消息是从控件传送给父窗口的消息。发送控件消息的控件在Visual C++中使用唯一ID号来进行标识,使用控件类来操纵相应的控件。与标准Windows消息一样,控件消息也在视图类、窗口类进行处理。但是,如果用户单击按钮控件,所发出的控件通知消息BN_CLICKED将作为命令消息来处理。 3. 命令消息(WM_COMMAND) 命令消息是菜单项、工具栏按钮、加速键等用户界面对象发送的WM_COMMAND消息。命令消息可以被文档、视图、窗口、应用程序等对象处理。发送命令消息的用户界面对象在Visual C++中也使用唯一的ID号来标识。通过给界面和命令消息分配相同的ID号,可以把用户界面对象与命令联系起来。 Windows把非命令消息直接发送给窗口类对象,该窗口类中用于处理该消息的处理函数将被调用。但是,对于命令消息,将把命令消息发送给多个候选对象(称为命令目标),目标中总有一个将调用该命令的处理函数。 注意:由于CWnd类派生于CCmdTarget类,所以凡是从CWnd派生的类,他们既可以接收标准消息,也可以接收命令消息和通告消息。而对于从CCmdTarget类派生的类只能接收命令消息和通告消息,不能接受标准消息。 ********************************************************************************************** MFC是Windows下程序设计的最流行的一个类库,但是该类库比较庞杂,尤其是它的消息映射机制,更是涉及到很多低层的东西,首先我在这里描述一下,Windows 的消息种类: 一般分的话有三种: 1. 标准消息:除了WM_COMMAND,所有的以WM 开头的消息都是标准消息,从CWnd 派生的类,都可以接受此消息。

窗口创建及窗口消息映射

进入MFC讲坛的前言 2008-02-14 10:53:59 分类:WINDOWS MFC中的窗口创建及窗口消息映射 我经常碰到有人问我有关窗口创建的问题,他们经常把用HWND描述的系统窗口对象和用CWnd描述的MFC的窗口对象混淆不清。这两者之间是紧密联系在一起的,但是MFC为了自身的管理,在CWnd中加了一些额外的内容,包括如何从HWND生成CWnd。 在MFC中,有几种典型的窗口对象,CWnd描述的一般窗口对象,CView描述的视图对象,CFrameWnd描述的SDI框窗对象,CMDIFrameWnd描述的MDI框窗对象等等。在这一章中,主要讨论下述内容: MFC中窗口的创建 MFC的消息映射机制(MESSAGE MAP) 对于上面两点MFC的设计者们使用了很高的技巧来确保应用程序的代码尽可能小,其中的技巧和隐藏在它们背后的思想值得我们学习。下面对各项内容进行讨论。 MFC中窗口的创建 在Window下,创建窗口可以使用两个函数,CreateWindow()和CreateWindowEx(),它们都需要一个参数,这个参数是标识窗口类的字符串。所以,如果要创建窗口,一般的做法是,先使用RegisterClass()或RegisterClassEx()注册一个窗口类,然后使用该窗口类来创建窗口。在前面我也提到过,注册窗口类的最主要目的是为系统提供窗口函数的地址,以便被DispatchMessage()之类的函数回。 在MFC中,创建窗口的函数是CWnd或其派生类的Create()或CreateEx方法,注册窗口类一般使用AfxRegisterWndClass(),在这个全局函数中,并没有发现窗口函数地址这样的参数,因此脑子里自然就会有这样的问题:窗口函数在

常用快捷键:窗口和对话框

常用快捷键:窗口和对话框 窗口和对话框 ①在文档和程序窗口中移动 Alt+Tab 切换至下一个程序或Microsoft Word文档窗口 Alt+Shift+Tab 切换至上一个程序或Microsoft Word文档窗口 Ctrl+Esc 显示Microsoft Windows"开始"菜单 Ctrl+W 关闭活动文档窗口 Ctrl+F5 将已最大化的活动文档窗口还原 Ctrl+F6 切换至下一个Word文档窗口 Ctrl+Shift+F6 切换至上一个Word文档窗口 Ctrl+F7 按箭头键在文档窗口不处于最大化状态时,并按下Enter执行"移动"命令(单击标题栏中的文档图标可显示此命令) Ctrl+F8 按箭头键在文档窗口不处于最大化状态时,并按下Enter执行"大小"命令(单击标题栏中的文档图标可显示此命令) Ctrl+F10 最大化文档窗口

②在对话框中移动 Ctrl+Tab 切换至对话框中的下一张选项卡 Ctrl+Shift+Tab 切换至对话框中的上一张选项卡 Tab 移至下一选项或选项组 Shift+Tab 移至上一选项或选项组,箭头在所选列表中的选项间移动,或者在一组选项的选项间移动Spacebar执行所选按钮的指定操作;选中或清除复选框,字母在所选列表中,移动到以键入字母开始的下一选项 Alt+字母选择选项,或者选中或清除包含该字母(带有下划线)的选项名称旁的复选框 Alt+↓(选中列表时)打开所选列表 Esc(选中列表时)关闭所选列表 Enter 执行对话框中默认按钮的指定操作 Esc 取消命令并关闭对话框 ③“打开”和“另存为”对话框 Ctrl+F12 显示"打开"对话框 F12 显示"另存为"对话框

教学设计:操作窗口与对话框

操作窗口和对话框 广州市天河职业高级中学徐晓宏【学科】:计算机基础 【课型】:“任务引领型”活动课【课时】:1课时 【学习内容分析】 本次课学习内容是选自高等教育出版社《计算机应用基础教材》(WindowsXP+Office 2003)第二章“Windows XP操作系统”的“2.1Windows XP入门”任务4内容,在这次课里,学生主要是在前面任务3——认识WindowXP 窗口和对话框的基础上,进一步熟练掌握窗口及对话框相关操作。 【教学对象分析】 教学对象为是中职计算机专业一年级学生,学生活跃好动,喜欢自己动手探究。 学生来自广州市区,从小学开始接触过计算机,属于非零起点学生。他们对于Windows 操作比较熟悉,只是还没有形成比较系统化、清晰化的概念。 【教学目标】 【教学理念】 以游戏激趣法、行动导向法,探究发现法、任务驱动法为主,充分体现“做中学、做中

教”的教学理念,把促使学生学会学习、思考、研究、合作的思想渗透在整个教学过程中,通过发现方法,解决问题,最大限度地发挥学生的学习积极性。 从关注学生的个体差异出发,又采用了分层教学法、竞争激励法,使得全体学生都得到发展和提高。 【教学重难点】 重点:窗口和对话框的基本操作 难点: 1、帮助和支持中心的使用。 2、窗口的相关使用技巧。 【教学准备】 1、学习环境准备 (1)机房环境准备:学生机、多媒体广播系统 2、素材准备:“对号入座”小游戏、闯关游戏、学习视频课件、闯关记录表 3、学生准备:全体学生按座位相邻的进行分组,为小组竞赛学习做好准备。本次课将全 班学生分为4大组。 【教学过程】

【教学流程图】 符号表示法: 教学环节教师活动 学生活动

Win32消息大全

Win32消息大全 阿杰发表于:2007-8-1720:52来源:外挂基地 消息,就是指Windows发出的一个通知,告诉应用程序某个事情发生了。例如,单击鼠标、改变窗口尺寸、按下键盘上的一个键都会使Windows发送一个消息给应用程序。消息本身是作为一个记录传递给应用程序的,这个记录中包含了消息的类型以及其他信息。例如,对于单击鼠标所产生的消息来说,这个记录中包含了单击鼠标时的坐标。这个记录类型叫做TMsg, 它在Windows单元中是这样声明的: type TMsg=packed record hwnd:HWND;//窗口句柄 message:UINT;//消息常量标识符 wParam:WPARAM;//32位消息的特定附加信息 lParam:LPARAM;//32位消息的特定附加信息 time:DWORD;//消息创建时的时间 pt:TPoint;//消息创建时的鼠标位置 end; 消息中有什么?

是否觉得一个消息记录中的信息像希腊语一样?如果是这样,那么看一看下面的解释: hwnd32位的窗口句柄。窗口可以是任何类型的屏幕对象,因为Win32能够维护大多数可视对象的句柄(窗口、对话框、按钮、编辑框等)。 message用于区别其他消息的常量值,这些常量可以是Windows单元中预定义的常量,也可以是自定义的常量。 wParam通常是一个与消息有关的常量值,也可能是窗口或控件的句柄。 lParam通常是一个指向内存中数据的指针。由于W P a r a m、l P a r a m和P o i n t e r 都是32位的, 因此,它们之间可以相互转换。 WM_NULL=$0000; WM_CREATE=$0001; 应用程序创建一个窗口 WM_DESTROY=$0002; 一个窗口被销毁 WM_MOVE=$0003; 移动一个窗口 WM_SIZE=$0005; 改变一个窗口的大小 WM_ACTIVATE=$0006;

Java窗口和消息提示框

Java窗口 ------------------------------------------- import java.awt.*; import javax.swing.*; public class MyWindow extends JFrame { public MyWindow(String title) { super(title); setSize(300,300); setLocation(30,50); setVisible(true); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } public static void main(String[] args) { new MyWindow("窗口"); } } JAVA 中提供如下消息提示框: JOptionPane.showMessageDialog(newFrame.getContentPane(),"弹出的是消息提示框!", "系统信息", https://www.doczj.com/doc/3c15033226.html,RMATION_MESSAGE); JOptionPane.showMessageDialog(newFrame.getContentPane(),"弹出的是警告提示框!", "系统信息", JOptionPane.WARNING_MESSAGE); JOptionPane.showMessageDialog(newFrame.getContentPane(),"弹出的是错误提示框!", "系统信息", JOptionPane.ERROR_MESSAGE); JOptionPane.showMessageDialog(newFrame.getContentPane(),"弹出的是询问提示框!", "系统信息", JOptionPane.QUESTION_MESSAGE);

消息对话框

//一。应用程序类 CDlogApp theApp; //唯一的应用程序类CDlogApp的实例对象 BOOL CDlog::InitInstance() //应用程序初始化 { AfxEnableControcontainer(); //标准初始化 CDlog dlg; //主对话框类实例对象 m_pMainWnd = &dlg; //赋给应用程序类成员int nResponse = dlg.DoModal(); //显示主对话框窗口 return FALSE; } //二。主对话框窗口类 //包含构造函数CDlogDlg,数据交换函数DoDataExchange,初始化对话框函数OnInitDialog,绘制函数OnPaint 等。 CDlogDlg::CDlogDlg(CWnd* pParent/*=NULL*/) //构造函数:CDialog(CDlogDlg::IDD,pParent) { m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); //载入对话框窗口图标 }

//动态数据交换 V oid CDlogDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); } //初始化对话框 BOOL CDlogDlg::OnInitDialog() { CDialog::OnInitDialog(); //将About菜单项添加到系统菜单 //设置对话框图标 //在此添加初始化代码 return TRUE; } //系统命令消息响应函数 BOOL CDlogDlg::OnSysCommand(UINT nID,LPARAM IParam) { if((nID&0xFFF0)==IDM_ABOUTBOX) { CAboutDlg dlgAbout; dlgAbout.DoModal(); }

认识窗口

第四课《认识窗口》 教学目标: 1、掌握打开窗口的方法。 2、了解窗口的组成。 教学内容: 1、打开窗口的方法。 2、窗口的组成。 教学重点: 打开窗口的方法和窗口各部分的名称。 教学难点: 窗口各部分的名称。 教法指导: 1、教师教授 2、任务驱动 3、学生讨论 4、实际操作 教学用具: 1、教具 2、多媒体 课时安排: 一课时 教学过程: 一、导入 1、回忆上节课学习内容,想想,在电脑完全开启之后,我们的显示器上显示了些什么?还有那个同学记得? 2、看上去有些同学已经忘记了,那好吧,让我们开启我们的电脑,进去看看是什么? (学生开启电脑)

3、师:“现在你们看到了什么?谁能来再说一说? 4、引出本节课课题。 二、新授 任务一、认识桌面上的“图标” 1、认识桌面。 2、桌面上都有些什么? (桌面背景、桌面图标、开始菜单、任务栏) 3、什么是桌面图标? (是windows中对使用的程序、文件的一种表示方式,图标可以通过双击打开。图标一方面告诉你它的名字,另一方面告诉你它和其他的不同,是自身的一个标志,像自己的脸,让别人看到后认识,也犹如一扇门,你可以打开他看到里面的很多东西) 4、认识常用图标 我的文档 我的电脑 回收站 其他图标的初步了解(程序、文件) 5、桌面图标打开的方法(双击),打开后关闭的方法。 任务二、掌握“开始”按钮的操作

1、教师讲解“开始”菜单的作用,使学生初步理解。 2、对“开始”菜单进行操作演示,使学生明白,电脑中有更多的东西他们都有一个犹如封皮的图标放在“开始”菜单里方便我们查找和使用。 3、教师演示“开始”菜单的基本操作。 ) 菜单内程序或者文件的打开方法(单击) 任务三、认识“任务栏: 通过讲解和演示来学习“任务栏”的作用和组成介绍,学生初步认识。 三、学生练习 动手操作:通过“开始”菜单打开“记事本”“画图”和“计算器”。 四、课堂小结 总结本节课所学知识及所掌握了的技能。 四、作业布置 1、熟记windows“桌面”的组成部分。 2、举例说明图标的作用。 3、对开始菜单操作练习。

教学设计操作窗口与对话框

操作窗口和对话框 【学科】:计算机基础 【课型】:“任务引领型”活动课 【课时】:1课时 【学习内容分析】 本次课学习内容是选自高等教育出版社《计算机应用基础教材》(WindowsXP+Office 2003)第二章“Windows XP操作系统”的“2.1Windows XP入门”任务4内容,在这次课里,学生主要是在前面任务3——认识WindowXP 窗口和对话框的基础上,进一步熟练掌握窗口及对话框相关操作。 【教学对象分析】 教学对象为是中职计算机专业一年级学生,学生活跃好动,喜欢自己动手探究。 学生来自广州市区,从小学开始接触过计算机,属于非零起点学生。他们对于Windows 操作比较熟悉,只是还没有形成比较系统化、清晰化的概念。 【教学目标】 【教学理念】 以游戏激趣法、行动导向法,探究发现法、任务驱动法为主,充分体现“做中学、做中

教”的教学理念,把促使学生学会学习、思考、研究、合作的思想渗透在整个教学过程中,通过发现方法,解决问题,最大限度地发挥学生的学习积极性。 从关注学生的个体差异出发,又采用了分层教学法、竞争激励法,使得全体学生都得到发展和提高。 【教学重难点】 重点:窗口和对话框的基本操作 难点: 1、帮助和支持中心的使用。 2、窗口的相关使用技巧。 【教学准备】 1、学习环境准备 (1)机房环境准备:学生机、多媒体广播系统 2、素材准备:“对号入座”小游戏、闯关游戏、学习视频课件、闯关记录表 3、学生准备:全体学生按座位相邻的进行分组,为小组竞赛学习做好准备。本次课将全 班学生分为4大组。 【教学过程】

【教学流程图】 符号表示法: 教学环节教师活动 学生活动

父窗口与子窗口的消息传递

[原]关于MFC中父窗口与子窗口子窗口与子窗口之间的信息传递及控制 2013-6-25阅读5993评论1 因为项目的需要,某子窗口B的设置变动,经常需要联动其他子窗口C,或者父窗口A控件的名称更新,数据更新等等问题。再网上查了许久,不得解 ,特抛砖引玉,提供几种思路。 以下都以A为父窗口,A1为A中的Tab控件,B和C为子窗口被非模态创建于A1上,所以之间的关系为 A | A1 A2 A3 (An为A上控件) | B C | C1 C2 C3 (Cn 为C上控件) 一、发送消息 1、自定义消息,网上很多 https://www.doczj.com/doc/3c15033226.html,/s/blog_4a1695ff0100ckgo.html 自定义消息中,加入自己要更新的消息内容,如果控件颜色,文字等等。 2、在A类中定义C类的对象page2 即可通过调用page2.SendMessage(WM_MYMSG, NULL, NULL); 实现。 二、如果在C中的控件要控制A2的数据显示。 GetParent()->GetParent()->SetDlgItemText(A2, "XXXXX"); 实现。 其中,第一个getparent()获得A1的窗口指针,第二个getparent()获得A的窗口指针。

三、通过二可以知道,其实每个控件都是一个子窗口,它可以包含其他子窗口,成为Parent. 我们通过GetParent()或的A1的窗口指针之后,可以通过FindWindow()等其他方式获得C的窗口指针,然后进行如二中的操作。 四、刚发现的一种方式,比如主对话框中MainDlg.cpp 中,子类或者对话框中Page.cpp中使用主对话框的资源。 1、在MainDlg.cpp中传输自己的对象到Page.cpp中。 PageX.SetDlgPtr(this); 2、在Page.cpp中成员函数:void SetDlgPtr(class MainDlg *p){ m_pDlg = p; } 成员变量: class MainDlg *m_pDlg; 3、使用m_pDlg使用MainDlg中的函数控制控件的显示信息。 五、其他

Windows 所有消息 的列表

hwnd 32位的窗口句柄。窗口可以是任何类型的屏幕对象,因为Win32能够维护大多数可视对象的句柄(窗口、对话框、按钮、编辑框等)。 message 用于区别其他消息的常量值,这些常量可以是Windows单元中预定义的常量,也可以是自定义的常量。 wParam 通常是一个与消息有关的常量值,也可能是窗口或控件的句柄。 lParam 通常是一个指向内存中数据的指针。由于W P a r a m、l P a r a m 和P o i n t e r都是3 2位的,因此,它们之间可以相互转换。 WM_NULL = $0000; WM_CREATE = $0001; 应用程序创建一个窗口 WM_DESTROY = $0002; 一个窗口被销毁 WM_MOVE = $0003; 移动一个窗口 WM_SIZE = $0005; 改变一个窗口的大小 WM_ACTIVATE = $0006; 一个窗口被激活或失去激活状态; WM_SETFOCUS = $0007; 获得焦点后 WM_KILLFOCUS = $0008; 失去焦点 WM_ENABLE = $000A; 改变enable状态

WM_SETREDRAW = $000B; 设置窗口是否能重画 WM_SETTEXT = $000C; 应用程序发送此消息来设置一个窗口的文本 WM_GETTEXT = $000D; 应用程序发送此消息来复制对应窗口的文本到缓冲区 WM_GETTEXTLENGTH = $000E; 得到与一个窗口有关的文本的长度(不包含空字符) WM_PAINT = $000F; 要求一个窗口重画自己 WM_CLOSE = $0010; 当一个窗口或应用程序要关闭时发送一个信号 WM_QUERYENDSESSION = $0011; 当用户选择结束对话框或程序自己调用ExitWindows函数WM_QUIT = $0012; 用来结束程序运行或当程序调用postquitmessage函数 WM_QUERYOPEN = $0013; 当用户窗口恢复以前的大小位置时,把此消息发送给某个图标WM_ERASEBKGND = $0014; 当窗口背景必须被擦除时(例在窗口改变大小时) WM_SYSCOLORCHANGE = $0015; 当系统颜色改变时,发送此消息给所有顶级窗口 WM_ENDSESSION = $0016;

对话框与窗口的区别

对话框与窗口的区别: 对话框与窗口很相似,但是工作起来不同,因为对话框不能改变大小,而窗口一般都可以进行最大化和最小化等操作。一般而言,当屏幕显示一个对话框时,对文档窗口的其他操作将不起作用,直到该对话框关闭为止。 电脑里的屏幕保护程序有什么用处,得分情况讨论。 部分电脑的屏幕保护程序有省电的作用(因为有的显示器在屏幕保护作用下屏幕亮度小于工作时的亮度这样有助于省电),更重要的是还可以保护你的显示器。(在未启动屏保的情况下)当你长时间不使用电脑的时候显示器的屏幕长时间显示不变的画面,这将会使屏幕发光器件疲劳变色/甚至烧毁/最终使屏幕,某个区域偏色或变暗. 活动课题:认识Windows98窗口 教学重点:移动窗口、改变窗口大小、最小化窗口的关闭 教学难点:窗口操作的综合应用 教学方法:任务驱动法、演示与讲解相结合、赏识教育法 协作学习法、练习法、讨论与自学相结合 一、出示问题:Windows98操作系统的特点是什么? 指名学生回答:通过显示在屏幕上一个个“窗口”,与电脑进行交流,并指挥电脑工作,每运行一个应用程序,都会打开一个窗口。(学生回答后,出示答案) 引出问题:那么,Windows98窗口是由哪几个部分组成的,每一组成部分又有怎样的功能呢? 引出课题并出示:以前面我们学习汉字输入时打开的“写字板”窗口为例,这节课让我们共同来认识Windows窗口。 二、学习过程: (一)出示学习任务。 将本节内容分解为两个大的任务:窗口组成观察和各组成部分的功能使用。 (目的:让学生对学习内容有直观认识,通过设置学习任务驱动学生自主学习和协作学习能力的培养。) (二)出示学习目标,明确学习目的。 (三)任务解决过程: 组成:分为标题栏、菜单栏、工具栏、最大化按钮、最小化按钮、关闭按钮。 教师指导:请同学们打开“写字板”,对照课本P35插图认识“写字板”窗口的组成,并分别找到这6个组成部分。

窗口机制 消息循环 消息队列

注:以下所说windows线程是指与调用了与图形用户界面相关的函数的线程,而windows 进程则是包含windows线程的进程,以区别于一般的进程和线程 一个线程只有一个报文队列,但可以有多个窗口,每个窗口都有WndProc函数 窗口对象如下: Typedef struct _WINDOW_OBJECT{ PW32THREADINFO ti; PDESKTOP Desktop; …… UNICODE_STRING WindowName; …… RECT WindowRect; …… //pointer to the owning thread’s message queue PUSER_MESSAGE_QUEUE MessageQueue; //指向所属进程的消息队列 Struct _WINDOW_OBJECT *FirstChild; Struct _WINDOW_OBJECT *LastChild; Struct _WINDOW_OBJECT *NextSibling; Struct _WINDOW_OBJECT *PrevSibling; //ENTRY in the list of thread windows LIST_ENTRY ThreadListEntry; //Handle to the owner window HWND hOwner; …… WNDPROC WndProc; //消息处理函数 PRTHREAD OwnerThread; //指向具体窗口所属线程的ETHREAD结构 …… }WINDOW_OBJECT; 当一个线程第一次被建立时,系统假定线程不会被用于任何与用户相关的任务。这样可以减少线程对系统资源的要求。但是,一旦这个线程调用一个与图形用户界面有关的函数(例如检查它的消息队列或建立一个窗口),系统就会为该线程分配一些另外的资源,以便它能够执行与用户界面有关的任务。因此进程在建立之初,并没有与用户界面相关的数据结构,只有当进程中某一线程调用win32k.sys中的函数时,进程会转化为windows进程,调用为win2k.sys的线程则转化为windows线程。一个进程只要其中有一个线程是windows线程,则就是windows进程。Windows进程除了EPROCESS和KPROCESS外,还有个W32PROCESS结构,即系统为windows进程所分配的另外一些资源。且EPROCESS结构中的指针Win32Process指向这个数据结构。 当线程转化为windows线程时,系统会为线程分配一个T H R E A D I N F O结构 这个T H R E A D I N F O结构包含一组成员变量,利用这组成员,线程可以认为它是在自己独占的环境中运行。T H R E A D I N F O是一个内部的、未公开的数据结构,用来指定线程的投递消息队列(posted-message queue)、发送消息队列(send-message queue)、应答消息队列(r e p l y -message queue)、虚拟输入队列(virtualized-input queue)、唤醒标志(wake flag)、以及用来描述线程局部输入状态的若干变量。

拦截窗口消息的示例

拦截窗口消息的示例 易语言等可视化编程已经将视窗消息封装为对象的属性、方法和事件。 当我们在窗口中按下鼠标左键,欲出现信息“你点击了窗体”,在易语言中是这样编写的: 子程序:__启动窗口_鼠标左键被按下 返回值类型:逻辑型 参数:横向位置数据类型:整数型 参数:纵向位置数据类型:整数型 参数:功能键状态数据类型:整数型 信息框(“你点击了窗体”, 0, ) 但是如果不用“__启动窗口_鼠标左键被按下”事件能否达到这样的结果? 由于对象的事件也只不过是视窗消息的封装,所以我们可以用视窗消息实现这样的功能。 我们需要用到两个API函数:拦截窗口消息函数SetWindowLongA(置窗口信息)、 回调函数CallWindowProcA(调窗口信息)。SetWindowLongA用于随时拦截各种窗口消息, 通过判断不同的消息类型执行不同的代码(类似于易语言“事件”的作用); CallWindowProcA用于没有出现需要的消息类型时,将程序的消息返回到操作系统中, 使操作系统继续用SetWindowLongA来拦截窗口消息。 请看下面的示例代码: Dll命令:置窗口信息 返回值类型:整数型 Dll库文件名:user32.dll 在Dll库中的命令名:SetWindowLongA 参数:窗口句柄数据类型:整数型 参数:取回信息数据类型:整数型 参数:信息新值数据类型:子程序指针 Dll命令:调窗口信息 返回值类型:整数型 Dll库文件名:user32.dll

在Dll库中的命令名:CallWindowProcA 参数:过程指针数据类型:整数型 参数:过程句柄数据类型:整数型 参数:消息类型数据类型:整数型 参数:特定信息1 数据类型:整数型 参数:特定信息2 数据类型:整数型 ------------------------------ 常量:窗信_系统命令值:274 备注:WM_SYSCOMMAND 常量:窗信_鼠标按下值:513 备注:WM_LBUTTONDOWN ------------------------------ 窗口程序集:窗口程序集1 程序集容器:指针数据类型:子程序指针 程序集容器:旧窗口信息数据类型:整数型 程序集容器:旧句柄信息数据类型:整数型 ------------------------------ 子程序:__启动窗口_创建完毕 指针= &回调信息 旧窗口信息=置窗口信息 (取窗口句柄 (), -4, 指针) ------------------------------ 子程序:回调信息 返回值类型:整数型 备注:回调列表框 参数:窗口句柄数据类型:整数型 参数:信息类型数据类型:整数型 参数:值1 数据类型:整数型 参数:值2 数据类型:整数型 判断 (信息类型= #窗信_鼠标按下) 信息框(“你点击了窗体”, 0, ) 判断 (信息类型= #窗信_系统命令) 如果 (值1 = 61536) 信息框(“你点击了关闭按钮”, 0, ) 否则 如果 (值1 = 61488)

windows消息大全

【Window 消息大全使用详解】 消息,就是指Windows发出的一个通知,告诉应用程序某个事情发生了。例如,单击鼠标、改变窗口尺寸、 按下键盘上的一个键都会使Windows发送一个消息给应用程序。消息本身是作为一个记录传递给应用程序的, 这个记录中包含了消息的类型以及其他信息。例如,对于单击鼠标所产生的消息来说,这个记录中包含了单击鼠 标时的坐标。这个记录类型叫做TMsg, 它在Windows单元中是这样声明的: type TMsg = packed record hwnd: HWND; / /窗口句柄 message: UINT; / /消息常量标识符 wParam: WPARAM ; // 32位消息的特定附加信息 lParam: LPARAM ; // 32位消息的特定附加信息 time: DWORD; / /消息建时的时间 pt: TPoint; / /消息建时的鼠标位置 end; 消息中有什么? 是否觉得一个消息记录中的信息像希腊语一样?如果是这样,那么看一看下面的解释: hwnd 32位的窗口句柄。窗口可以是任何类型的屏幕对象,因为Win32能够维护大多数可视对象的句柄(窗口、 对话框、按钮、编辑框等)。 message用于区别其他消息的常量值,这些常量可以是Windows单元中预定义的常量,也可以是自定义的常量。 wParam通常是一个与消息有关的常量值,也可能是窗口或控件的句柄。 lParam通常是一个指向内存中数据的指针。由于W P a r a m、l P a r a m和P o i n t e r都是3 2位的,因此,它们之间可以相互转换。 WM_NULL = $0000; WM_CREATE = $0001; 应用程序建一个窗口 WM_DESTROY = $0002; 一个窗口被销毁 WM_MOVE = $0003; 移动一个窗口 WM_SIZE = $0005;

C#中发送消息给指定的窗口,以及接收消息

如何在C#中发送消息给指定的窗口? public class Note { //声明API 函数 [DllImport("User32.dll", EntryPoint = "SendMessage")] private static extern IntPtr SendMessage(int hWnd, int msg, IntPtr wParam, IntPtr lParam); [DllImport("User32.dll", EntryPoint = "FindWindow")] private static extern int FindWindow(string lpClassName, string lpWindowName); //定义消息常数 public const int CUSTOM_MESSAGE = 0X400 + 2;//自定义消息 //向窗体发送消息的函数 public void SendMsgToMainForm(int MSG) { int WINDOW_HANDLER = FindWindow(null, "协同标绘"); if (WINDOW_HANDLER == 0) { throw new Exception("Could not find Main window!"); } long result = SendMessage(WINDOW_HANDLER, CUSTOM_MESSAGE, new IntPtr(14), IntPtr.Zero).ToInt64(); } } 在协同标绘窗口里拦截消息的函数: protected override void WndProc(ref System.Windows.Forms.Message msg) { switch (msg.Msg) { case Note.CUSTOM_MESSAGE: //处理消息 { switch (msg.WParam.ToString()) { case "11"://对象添加 string s = "mdesheng";

认识word窗口)

第一节认识word窗口 教学目标与任务: 1、掌握word的启动和退出 2、认识word的主窗口和文档窗口 3、了解窗口的基本组成部分与作用 4、学会创建桌面快捷方式 5、掌握文档的新建、保存和打开等操作 6、掌握文字输入与修改 7、掌握文档的新建、保存和打开等操作 教学重点与难点: 重点:认识文档窗口和视图的调整 文档的新建、保存和打开等操作 难点:多文档窗口,视图中工具栏的整齐排列 文档打印调整方法 课时安排与准备: 1课时。安装Office 2000 或word 2000软件 教材分析与说明: 1、word的启动与界面与写字板的比较:Word的基本界面与文字录入、编辑,与写字板一致。注意多文档窗口的演示以及关闭文档与退出word。 2、视图菜单的使用。 3、Word中的字体格式设置:word中的字体格式设置要比写字板非富得多,这里可以给学生稍作介绍; 4、适当演示动态效果文字:这是Word的一个十分出色的地方,也是学生很感兴趣的,因此可以提高学生学习word的积极性。 5、这里应留一定的时间,学生试一试,让学生自己去尝试摸索一下,看看他可以发现word有哪些功能。 教学课件演示 【教学过程】 一、导入(激发学生情感). 同学们,今天我很高兴和大家一起上这节课,老师带来一组幻灯片,让我们一起来看看吧!(播放幻灯片). 幻灯片看完了,现在请你们谈谈自己的想法和感受?(请学生说说自己的感受). 师:幻灯片中有一张是纯文字的,还有一张是含有文字、图片、艺术字、文本框、表格的。对于纯文字的文档,我们可以用记事本或写字板输入,但像含有文字、图片、艺术字、文本框、表格的文档,用记事本或写字板就输入不了,就需要功能更强大,更适合我们日常需要的文字处理软件,今天这节课,我们就来学习M icrosoft Word——文字处理软件。 二、授新 1、Word的打开与关闭 播放一段视频,让学生观察视频。 师:你们观察出了什么。(1)、Word是怎么打开的?(2)、Word是怎么关闭的?(板书) 师:那你能不能照着上面的演示做一遍呢?(学生说,教师板书工具图)

Windows2000窗口及对话框的组成和操作

Windows2000操作系统 教学对象分析: Windows2000操作系统已应用多年,部分学生也经常使用它,这就为本章节的教学提供了良好的基础,但也有相当多的同学由于受条件的限制,尚未接触或没有系统地学习Windows2000。Windows2000以图形界面、鼠标操作为主,操作简捷,容易激发学生学习兴趣。由于部分学生已使用过Windows2000,他们在学习过程中不重视有关基础知识的学习,喜欢玩玩游戏,这就需要老师做好引导的工作。 情感态度与价值观: 了解Windows2000操作系统等计算机技术在信息社会发展中所起的作用。明确学习目的,激发和保持学习兴趣,培养自主学习的精神。 教学内容: Windows2000桌面、窗口及对话框的组成 教学重点与难点: 1、Windows2000的桌面组成 2、Windows2000窗口和对话框的组成及操作 教学过程: 一、导入 师简述Window2000操作系统的特点(1、界面友好;2、多任务系统;3、支持多屏幕显示;4、网络管理方便、安全;5、设备管理功能强大;6、与Internet集成。)启动Windows2000系统,单击“确定”或回车键即可进入。 二、授课 1、Windows2000的桌面 师述并演示:Windows系统登陆成功进入的第一个界面称“桌面”,系统安装完成后桌面上一般形成以下几个图标: (1)我的电脑:管理计算机内的所有资源 (2)我的文档:用户文件的管理 (3)网上邻居:网络浏览及文件共享 (4)IE浏览器:启动网页浏览器以浏览网页信息 (5)回收站:存放被删除的对象及对被错误删除对象的恢复 (6)任务栏:用来显示所有已经打开的窗口图标,单击任务栏中的窗口图标,可以激活

ansys中几种对话框的认识与设置

ansys中几种对话框的认识与设置 1.图形变换对话框按快捷功能图标或utility\PlotCtrls\Pan Zoom Rote 出现下面所示图形变换对话框 图形变换对话框 1. windows 后面选择有1. 2.3……all 当对某个对象进行图形变换时就选择对应的编号。选al时,则所有的窗口都变换

2.Front +Z向视图 Top +Y向视图 Right +X向视图 Back —Z向视图 Bot —Y向视图 Light —X向视图 Iso 等轴视图 Obliq斜视图 WP 工作平面视图 3.拾取矩形窗口的图形 Zoom:中心点+矩形区域内的任意点 Box Zoom:角点+对角点 WIn Zoom角点+其他边线上的一点 Back Up:退回到最后一次图形变换前的显示状态 4.Dynamic Mode选中时 Mode:可以用鼠标动态进行图形变换 Lights:可以用鼠标动态进行光源变换 Ctrl+鼠标左键:360度平移模型或光源 Ctrl+鼠标中建:前后移动缩放、左右移动旋转模型或光源 Ctrl+鼠标右键:旋转模型或光源 5.Fit 单击使整个模型自适应充满整个图形窗口 2.图形拾取对话框

图形拾取对话框 1.选取方法 single:用鼠标逐个拾取对象Box:定义一个矩形框选取对象Circle:定义一个圆形拾取对象Loop:鼠标选取对象 2.拾取对象状态信息 count:总数目 maximum:最大拾取数目minimum:最小数去数目

3.对象拾取模式切换 list of Items 鼠标拾取 min max inc人工定义编号拾取 4.reset:清空所有拾取,回复到重新拾取状态3.工作平面对话框(显示与捕捉) 工作平面设置对话框 Cartesian:直角坐标 Polar:极坐标

相关主题
文本预览
相关文档 最新文档