1. 对窗口和挂钩(hook)这两种user对象,它们分别由建立窗口和安装挂钩的线程所拥有。
2. 建立窗口的线程必须是为窗口处理所有消息的线程。
3. 一旦这个线程调用一个与图形用户界面有关的函数(例如检查他的消息队列或建立一个窗口),系统就会为该线程分配一些另外的资源,以便他能够执行与用户界面有关的任务。特别是,系统分配一个THREADINFO结构,并将这个数据结构域线程联系起来。
4. 消息被放置在线程的登记消息队列中,这要通过调用PostMessage函数完成:
BOOL PostMessage(
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam);
函数PostMessage在等急了消息之后立即返回,调用该函数的线程不知道等级的消息是否被制定的窗口的窗口过程处理。
5. 可以通过调用GetWindowThreadProcessId来确定是那个线程建立了一个窗口
DWORD GetWindowThreadProcessId(
HWND hwnd,
pdword PDWpROCESSiD);
6. 使用SendMessage函数可以将窗口消息直接发送给一个窗口过程:
LRESULT SendMessage(
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam);
窗口过程将处理这个消息。只有当消息被处理之后,SendMessage才能返回到调用程序。
7. 当一个线程等待SendMessage返回时,它基本上是处于空闲状态。但它可以执行一个任务:如果系统中另外一个线程向一个窗口发送消息,这个窗口是由这个等待SendMessage返回的线程所创建的,则系统要立即处理发送的消息。
8.
LRESULT SendMessageTimeout(
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam,
UINT fuFlags,
UINT uTimeout,
PDWORD_PTR pdwResult);
利用SendMessageTimeout函数,可以规定等待其他线程大会你消息的时间最大值。
9.
BOOL SendMessageCallback(
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam,
SENDASYNCROPC pfnResultCallBack,
ULONG_PTR dwData);
当一个线程调用SendMessageCallback时,该函数发送消息到接收的发送消息队列,并立即返回时发送线程可以继续执行。当接收线程完成对消息的处理时,一个消息被登记到发送线程的应答消息队列中。然后,系统通过调用一个函数将这个应答通知给发送线程,该函数是使用下面的原型编写的:
VOID CALLBACK ResultCallBack(
HWND hwnd,
UINT uMsg,
ULONG_PTR dwData,
LRESULT lResult);
10. SendMessageCallback函数还有另外一个用处。Windows提供了一种广播消息的方法,用这种方法你可以向提供中所有现存的重叠(overlapped)窗口广播一个消息。这可以通过调用SendMessage函数,对参数hwnd床底HWND_BROADCAST(定义为-1)。
11.
BOOL SendNotifyMessage(
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam);
SendNotifyMessage建一个消息置于接收线程的发送消息队列中,并立即返回到调用线程。这一点与PostMessage函数一样,但SendNotifyMessage在两方面与PostMessage不同。首先,SendNotifyMessage是向另外的线程所建立的窗口发送消息,发送的消息比起接收线程消息队列中存放的等级消息有更高的优先级。其次,当想一个有调用进程建立的窗口发送消息时,SendNotifyMessage同SendMessage函数完全一样:SendNotifyMessage在消息被处理完之后才能返回。
12.
BOOL ReplyMessage(RSULT lResult);
线程调用ReplyMessage是为了接收窗口消息。当一个线程调用ReplyMessage时,它是要告诉系统,为了知道消息结果,它已经完成了足够的工作,结果应该包装起来并登记到发送线程的应答消息队列中。这将使发送线程醒来,获得结果,并继续执行。
13. 当一个线程正在运行时,它可以通过调用GetQueueStatus函数来查询队列的状态
DWORD GetQueueStatus(UINT fuFlags);
14. 一个线程可以调用MsgWaitForMultipleObjects或MsgWaitForMultipleObjstsEx函数,使线程等待他自己的消息:
DWORD MsgWaitForMultipleObjects(
DWORD nCount,
PHANDLE phObjects,
BOOL fWaitAll,
DWORD dwMillisconds,
DWORD dwWakeMask);
DWORD MsgWaitForMultipleObjectsEx(
DWORD nCount,
PHANDLE phObjects,
DWORD dwMilliseconds,
DWORD dwWakeMask,
DWORD dwFlags);
15. 如果你要建立自己的(WM_USER+x)消息,并从一个进程向另一个进程的窗口发送,那又会怎么样?系统不知道你要用内存映射文件并在发送消息是改变指针。为此,微软建立了一个特殊的窗口消息,WM_COPYDATA已解决这个问题:
COPYDATASTRUCT cds;
SendMessage(hwndReceiver, WM_COPYTDATA, (WPARAM)hwndSender, (LPARAM)&cds);