怎样对Windows消息进行拦截

怎样对Windows消息进行拦截,第1张

通过多进程来实现,用这两个命令:

调用格式: 〈逻辑型〉 启动线程 (子程序指针 欲执行的子程序,[整数型 参数数据],[整数型变量 线程句柄]) - 多线程支持库->多线程控制

英文名称:CreateThread

创建并启动一条线程,可重复使用以创建多条线程,成功返回真,失败返回假。本命令为初级命令。

参数<1>的名称为“欲执行的子程序”,类型为“子程序指针(SubPtr)”。本参数提供创建线程时欲启动的子程序,根据是否需要传递参数数据,该子程序必须没有或具有一个整数型参数,否则将出错。

参数<2>的名称为“参数数据”,类型为“整数型(int)”,可以被省略。本参数提供线程被启动时传递到欲启动子程序的整数数据。如果本参数未被省略,此时被启动子程序必须接收一个整数型参数,否则将出错。

参数<3>的名称为“线程句柄”,类型为“整数型(int)”,可以被省略,提供参数数据时只能提供变量。如果提供了本参数,将向参数变量写入线程句柄(Windows下为HANDLE,Linux下为pthread_t),请在适当的时机关闭该句柄。如果不提供本参数接收线程句柄,内部将自动处理线程句柄。

*** 作系统需求: Windows、Linux

————————————————————————————————————————

调用格式: 〈逻辑型〉 关闭线程句柄 (整数型 线程句柄) - 多线程支持库->多线程控制

英文名称:CloseThreadHandle

返回真表示已成功关闭线程句柄。在Linux下,如果线程已经结束,本命令可能返回假。本命令为初级命令。

参数<1>的名称为“线程句柄”,类型为“整数型(int)”。可通过“启动线程”的第三个参数获取线程句柄。

*** 作系统需求: Windows、Linux

======================================================================

按F1关闭线程,要注册热键:

调用格式: 〈整数型〉 注册热键 (整数型 窗口句柄,整数型 标签句柄,整数型 功能键,整数型 主热键) - 扩展功能支持库一->热键功能

英文名称:RegHotKey

注册系统热键,返回一个热键标识,失败返回0。本命令为初级命令。

参数<1>的名称为“窗口句柄”,类型为“整数型(int)”。窗口句柄。

参数<2>的名称为“标签句柄”,类型为“整数型(int)”。使用标签的反馈事件来接受热键,反馈事件中的第一个参数为热键标识,第二个参数无效。

参数<3>的名称为“功能键”,类型为“整数型(int)”,初始值为“0”。可以为:0-无功能键;1-CTRL键状态;2-SHIFT键状态;4-ALT键状态或各键状态值之和。

参数<4>的名称为“主热键”,类型为“整数型(int)”。键代码,可以使用易语言中的键代码常量。

*** 作系统需求: Windows

在多线程的程序中,很少有多个线程能在其生命期内进行完全独立的 *** 作;通常情况是一些线程进行某些 *** 作,而其他的线程必须对其 *** 作后的结果进行了解。如果不采取同步机制,其他线程会在线程处理任务前访问处理结果,这样会产生错误的了解。例如,多个线程同时访问同一个全局变量,如果都是读取 *** 作,则不会出现问题;若一个线程负责写 *** 作,其他线程负责读取 *** 作,则不能保证读取的就是修改过的值,这时就必须在变量写 *** 作过程时加上访问限制,在写 *** 作完成后解除访问限制。这种保证线程能正确获取其他线程处理结束后的结果的措施称为线程同步。

线程同步的四种方式:

临界区(Critical Section) :通过对多线程的串行化来访问公共资源或一段代码,本身不是内核对象,速度快,适合控制数据访问。在任意时刻只允许一个线程对共享资源进行访问,如果有多个线程试图访问公共资源,那么在有一个线程进入后,其他试图访问公共资源的线程将被挂起,并一直等到进入临界区的线程离开。临界区被释放后,其他线程才可以抢占。

初始化临界区

删除临界区

获取临界区

释放临界区

临界区在使用时,以 CRITICAL_SECTION 结构对象保护共享资源,并分别用 EnterCriticalSection() 和 LeaveCriticalSection() 函数占有和释放一个临界区。所用到的 CRITICAL_SECTION 结构对象必须经过 InitializeCriticalSection() 的初始化后才能使用,而且必须确保所有线程中的任何试图访问此共享资源的代码都处在此临界区的保护之下。否则临界区将不会起到应有的作用,共享资源依然有被破坏的可能。

示例

互斥量(Mutex) :只有拥有互斥对象的线程才有访问公共资源的权限,因为互斥对象只有一个,所以能保证公共资源不会同时被多个线程访问。互斥不仅能实现同一应用程序的公共资源安全共享,还能实现不同应用程序的公共资源安全共享。

创建互斥量

销毁互斥量

获取互斥量

释放互斥量

互斥量被某一线程获取时为 non-signaled 状态,释放时进入 signaled 状态。因此,可以利用 WaitForSingleObject 函数验证互斥量是否已分配。互斥量在 WaitForSingleObject 函数返回时自动进入 non-signaled 状态,因为它是“ auto-reset ”模式的内核对象。

示例

信号量( Semaphore ) 是维护0到指定最大值之间的同步对象。信号量状态在其计数大于0时是有信号,而其计数是0时是无信号的。信号量对象在控制上可以支持有限数量共享资源的访问。

信号量的特点和用途可用下列几句话定义:

创建信号量

释放信号量

打开信号量

销毁信号量

示例

事件(Event) :是WIN32提供的最灵活的线程间同步方式,事件可以处于激发状态(signaled or true)或未激发状态(unsignal or false)。根据状态变迁方式的不同,事件可分为两类:

创建事件

当第二个参数传入TRUE时将创建manual-reset模式的事件对象,此时即使WaitForSingleObject函数返回也不会回到non-signaled状态。因此,在这种情况下,需要通过如下2个函数明确更改对象状态。

打开事件

复位事件

设置事件

传递事件对象句柄并希望改为non-signed状态时,应调用ResetEvent函数。如果希望改为signaled状态,则可以调用SetEvent函数。

示例

如何你在窗口函数case不返回的话这个窗口就会没响应的,你可以试试看在一个case里写Sleep(5000)

有些人已经说对了,GetMessage只负责从消息队列里面取出一条消息,TranslateMessage将键盘敲键的消息转换成WM_CHAR消息,DispatchMessage就负责调用你的窗口函数,其实相当于

DispatchMessage()

{

WinSunProc(): //事实上这里是通过你注册窗口类时候给Windows的函数指针来实现的,但是效果和直接调用一样。

}

现在整个流程就很清楚了,GetMessage -> DispatchMessage -> WinSunProc 然后再返回到主循环进行下一条消息的 *** 作,如果你在WinSunProc里面一直不返回,那么程序是无法处理下条消息的。

处理消息的时候如果又有其他消息过来是没关系的,Windows的GetMessage是从消息“队列”里面去消息的,没来得处理的消息是会排队在消息队列里面的,微软说了Windows的消息队列足够长,一般不会出现消息丢失的情况,具体没说多长,可能根据 *** 作系统版本不同有不同的长度限制。

另外GetMessage还有个特性,如果程序的消息队列是空的,也就是没有消息了,那么GetMessage就不会返回,直到等到下一条消息来再返回,Windows会将处于等待的程序转入Idle模式,所以那个while循环是不会出现CPU100%的占用率的。如果你希望在程序没有消息的时候在后台做点什么事情,那么就可以利用PeekMessage,典型的MFC就是利用了PeekMessage来运作消息循环的,PeekMessage在队列中有消息的时候则把消息取回,没消息的时候也会立刻返回,这样你就可以在没消息的时候做点别的事情。MFC的CWinApp类在Run这个函数中包含了消息循环,在没有消息的时候,Run会去调用CWinApp::OnIdle,默认的OnIdle会负责释放不需要再使用的动态连接库文件。如果Run里面的PeekMessage取到消息,他则调用CWinApp::PumpMessage函数,PumpMessage就负责调用DispatchMessage把消息转交给窗口函数。

贴下CWinApp::Run的代码:

int CWinThread::Run()

{

ASSERT_VALID(this);

_AFX_THREAD_STATE pState = AfxGetThreadState();

// for tracking the idle time state

BOOL bIdle = TRUE;

LONG lIdleCount = 0;

// acquire and dispatch messages until a WM_QUIT message is received

for (;;)

{

// phase1: check to see if we can do idle work

while (bIdle &&

!::PeekMessage(&(pState->m_msgCur), NULL, NULL, NULL, PM_NOREMOVE))

{

// call OnIdle while in bIdle state

if (!OnIdle(lIdleCount++))

bIdle = FALSE; // assume "no idle" state

}

// phase2: pump messages while available

do

{

// pump message, but quit on WM_QUIT

if (!PumpMessage())

return ExitInstance();

// reset "no idle" state after pumping "normal" message

//if (IsIdleMessage(&m_msgCur))

if (IsIdleMessage(&(pState->m_msgCur)))

{

bIdle = TRUE;

lIdleCount = 0;

}

} while (::PeekMessage(&(pState->m_msgCur), NULL, NULL, NULL, PM_NOREMOVE));

}

}

以上就是关于怎样对Windows消息进行拦截全部的内容,包括:怎样对Windows消息进行拦截、window进程运行在哪个cpu上c++、在Windows下多进程的实现等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/10129007.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-05
下一篇2023-05-05

发表评论

登录后才能评论

评论列表(0条)

    保存