当前位置:文档之家› WINDOWS的消息机制与回调机制

WINDOWS的消息机制与回调机制

WINDOWS的消息机制与回调机制
WINDOWS的消息机制与回调机制

WINDOWS的消息机制与回调机制

声明CALLBACK

调用(calling)机制从汇编时代起已经大量使用:准备一段现成的代码,调用者可以随时跳转至此段代码的起始地址,执行完后再返回跳转时的后续地址。CPU为此准备了现成的调用指令,调用时可以压栈保护现场,调用结束后从堆栈中弹出现场地址,以便自动返回。借堆栈保护现场,它使调用者和被调者可以互不相识,于是才有了后来的函数和构件.

此调用机制并非完美。回调函数就是一例。例如,写一个快速排序函数供他人调用,其中必包含比较大小。麻烦来了:此时并不知要比较的是何类数据--整数、浮点数、字符串?于是只好为每类数据制作一个不同的排序函数。更通行的办法是在函数参数中列一个回调函数地址,并通知调用者:君需自己准备一个比较函数,其中包含两个指针类参数,函数要比较此二指针所指数据之大小,并由函数返回值说明比较结果。排序函数借此调用者提供的函数来比较大小,借指针传递参数,可以全然不管所比较的数据类型。被调用者回头调用调用者的函数(够咬嘴的),故称其为回调(callback)。

Windows系统还包含着另一种更为广泛的回调机制,即消息机制。消息本是Windows的基本控制手段,乍看与函数调用无关,其实是一种变相的函数调用。发送消息的目的是通知收方运行一段预先准备好的代码,相当于调用一个函数。消息所附带的WParam和LParam相当于函数的参数,只不过比普通参数更通用一些。应用程序可以主动发送消息,更多情况下是坐等Windows发送消息。一旦消息进入所属消息队列,便检感兴趣的那些,跳转去执行相应的消息处理代码。操作系统本是为应用程序服务,由应用程序来调用。而应用程序一旦启动,却要反过来等待操作系统的调用。这分明也是一种回调,或者说是一种广义回调。其实,应用程序之间也可以形成这种回调。假如进程B收到进程A发来的消息,启动了一段代码,其中又向进程A发送消息,这就形成了回调。这种回调比较隐蔽,弄不好会搞成递归调用,若缺少终止条件,将会循环不已,直至把程序搞垮。若是故意编写成此递归调用,并设好终止条件,倒是很有意思。但这种程序结构太隐蔽,除非十分必要,还是不用为好。

利用消息也可以构成狭义回调。上面所举排序函数一例,可以把回调函数地址换成窗口handle。如此,当需要比较数据大小时,不是去调用回调函数,而是借API函数SendMessage 向指定窗口发送消息。收到消息方负责比较数据大小,把比较结果通过消息本身的返回值传给消息发送方。所实现的功能与回调函数并无不同。当然,此例中改为消息纯属画蛇添脚,反倒把程序搞得很慢。但其他情况下并非总是如此,特别是需要异步调用时,发送消息是一种不错的选择。假如回调函数中包含文件处理之类的低速处理,调用方等不得,需要把同步调用改为异步调用,去启动一个单独的线程,然后马上执行后续代码,其余的事让线程慢慢去做。一个替代办法是借API函数PostMessage发送一个异步消息,然后立即执行后续代码。这要比自己搞个线程省事许多,而且更安全。

如今我们是活在一个object时代。只要与编程有关,无论何事都离不开object。但object 并未消除回调,反而把它发扬光大,弄得到处都是,只不过大都以事件(event)的身份出现,镶嵌在某个结构之中,显得更正统,更容易被人接受。应用程序要使用某个构件,总要先弄清构件的属性、方法和事件,然后给构件属性赋值,在适当的时候调用适当的构件方法,还要给事件编写处理例程,以备构件代码来调用。何谓事件?它不过是一个指向事件例程的地址,与回调函数地址没什么区别。不过,此种回调方式比传统回调函数要高明许多。首先,它把让人不太舒服的回调函数变成一种自然而然的处理例程,使编程者顿觉气顺。再者,地址是一个危险的东西,用好了可使程序加速,用不好处处是陷阱,程序随时都会崩溃。现代编程方式总是想法把地址隐藏起来(隐藏比较彻底的如VB和Java),其代价是降低了程序效率。事件例程使编程者无需直接操作地址,但并不会使程序减速。

回调函数:

它是这样一种机制:调用者在初始化一个对象(这里的对象是泛指,包括OOP中的对象、全局函数等)时,将一些参数传递给对象,同时将一个调用者可以访问的函数地址传递给该对象(被调用者)。这个函数就是调用者和被调用者之间的一种通知约定,当约定的事件发生时,被调用者(一般会包含一个工作线程)就会按照回调函数地址调用该函数,并向被调用者返回一个结果。这种方式,调用者在一个线程,被调用者在另一个线程。

句柄:handle,handle的本意是把柄,把手的意思,就是一个标号。是你与操作系统打交道的东东。举个通俗的例子,比如你考上了大学,入学后,学校(操作系统)会给你一个学生证号。注意,这个号码是学校指定的,你无法自选。有了这个号码(学生证,假设一证多用)就可以享受学校提供的服务:如你就可以去图书馆借书,去食堂吃饭,去教室上课等等。但你不能到食堂里买啤酒,因为学校不允许这种服务。而在计算机中系统提供的服务就是API调用,你有了HANDLE,就可以理直气壮地向系统提出调用API 的服务。而指针的权力就大多了,有了指针你可以到处去喝酒,打架,学校(操作系统)管不着,所以句柄和指针的区别在于句柄只能调用系统提供的服务。而句柄虽然是一个能相互区别的号码,但与我们普通的ID号又有区别,普通的ID号是可以由程序员自己定义的,而句柄不行,它是对象生成时系统指定的,是为了区别系统中存在的各个对象,这个句柄不是由程序员符给的。实际应用中,最常用的就是文件句柄和窗口句柄。例如,窗口句柄的值是一个长整数,每个窗体都用一个句柄来表示。所以句柄是不会重复的,很多的函数都会用到窗体的句柄。

消息:一个消息由一个消息名称(UINT),和两个参数(WPARAM,LPARAM)组成。

windows的消息机制:消息”是windows运行机制中一个基本而又重要的概念。消息是一个报告事件发生的通知,消息驱动是围绕消息的产生与处理展开的,并依靠消息循环机制来实现。

某条消息可被视为某个事件的发生,比如点击鼠标。事件即可以由用户引发,也可以由应用程序产生,当然windows本身也能发出消息。windows是一个多任务操作系统,所以没有哪一个程序能够独占系统的资源,资源都是由windows统一管理的。那么某个程序是如何获得用户的信息呢?事实上,windows

在时刻监视着用户的每个举动,一旦发生了动作,就由windows捕捉而不是应用程序,windows分析该动作与哪一个程序相关,然后将动作以消息的形式发送给当前的应用程序。相反,应用程序也在时时等着消息的到来,一旦发现它的消息队列中有未处理的信息,就获取并分析该消息,并根据消息所包含的内容采取适当的动作来响应,并将结果返回给系统。

例如窗口程序,当用户点击按钮时候,这一动作被windows捕捉,并且以消息(ID和参数)的形式发给该窗口的消息队列,该窗口发现队列中有消息,就根据消息调用相应的过程进行处理,并将返回结果返回给系统。每个窗口本身都有一个窗口函数,未处理的消息就由它处理,例如拖动。

windows为每个线程维护了相应的消息队列,应用程序的任务就是不停地从特定的消息队列中获取消息、分析消息并处理消息,直到消息(WM_QUIT)为止。这个过程的程序结构称为“消息循环”。

函数回调与消息机制:可以看出,消息机制是一种特殊的函数回调。因为应用程序本是调用系统函数的,但是一旦启动就等待系统发来的消息,等到消息调用相应过程进行处理,相当于系统进行了回调。所以消息机制是一种广义的函数回调。

Windows消息机制要点

1. 窗口过程每个窗口会有一个称为窗口过程的回调函数(WndProc),它带有四个参数,分别为:窗口句柄(Window Handle),消息ID(Message ID),和两个消息参数(wParam, lParam), 当窗口收到消息时系统就会调用此窗口过程来处理消息。(所以叫回调函数)2消息类型

1)系统定义消息(System-Defined Messages)

在SDK中事先定义好的消息,非用户定义的,其范围在[0x0000, 0x03ff]之间,可以分为以下三类:

1>窗口消息(Windows Message)

与窗口的内部运作有关,如创建窗口,绘制窗口,销毁窗口等。可以是一般的窗口,也可以是Dialog,控件等。

如:WM_CREATE, WM_PAINT, WM_MOUSEMOVE, WM_CTLCOLOR,

WM_HSCROLL...

2>命令消息(Command Message)

与处理用户请求有关,如单击菜单项或工具栏或控件时,就会产生命令消息。

WM_COMMAND, LOWORD(wParam)表示菜单项,工具栏按钮或控件的ID。如果是控件, HIWORD(wParam)表示控件消息类型

3>控件通知(Notify Message)

控件通知消息,这是最灵活的消息格式,其Message, wParam, lParam分别为:

WM_NOTIFY, 控件ID,指向NMHDR的指针。NMHDR包含控件通知的内容,可以任意扩展。

2)程序定义消息(Application-Defined Messages)

用户自定义的消息,对于其范围有如下规定:WM_USER: 0x0400-0x7FFF (ex.

WM_USER+10) WM_APP(winver>4.0): 0x8000-0xBFFF (ex.WM_APP+4)

RegisterWindowMessage: 0xC000-0xFFFF

3消息队列(Message Queues)

Windows中有两种类型的消息队列

1)系统消息队列(System Message Queue)

这是一个系统唯一的Queue,设备驱动(mouse, keyboard)会把操作输入转化成消息存在系统队列中,然后系统会把此消息放到目标窗口所在的线程的消息队列(thread-specific message queue)中等待处理

2)线程消息队列(Thread-specific Message Queue)

每一个GUI线程都会维护这样一个线程消息队列。(这个队列只有在线程调用GDI函数时才会创建,默认不创建)。然后线程消息队列中的消息会被送到相应的窗口过程(WndProc)处理.注意:线程消息队列中WM_PAINT,WM_TIMER只有在Queue中没有其他消息的时候才会被处理,WM_PAINT消息还会被合并以提高效率。其他所有消息以先进先出(FIFO)的方式被处理。

4队列消息(Queued Messages)和非队列消息(Non-Queued Messages)

1)队列消息(Queued Messages)

消息会先保存在消息队列中,消息循环会从此队列中取消息并分发到各窗口处理如鼠标,键盘消息。

2)非队列消息(NonQueued Messages)

消息会绕过系统消息队列和线程消息队列直接发送到窗口过程被处理

如:WM_ACTIVATE, WM_SETFOCUS, WM_SETCURSOR,

WM_WINDOWPOSCHANGED注意: postMessage发送的消息是队列消息,它会把消息Post 到消息队列中;SendMessage发送的消息是非队列消息,被直接送到窗口过程处理

5 PostMessage(PostThreadMessage), SendMessage PostMessage:把消息放到指定窗口所在的线程消息队列中后立即返回。PostThreadMessage:把消息放到指定线程的消息队列中后立即返回。

SendMessage:直接把消息送到窗口过程处理,处理完了才返回。

6 GetMessage, PeekMessage

PeekMessage会立即返回可以保留消息

GetMessage在有消息时返回会删除消息

7 TranslateMessage, TranslateAccelerator TranslateMessage: 把一个virtual-key消息转化成字符消息(character message),并放到当前线程的消息队列中,消息循环下一次取出处理。

TranslateAccelerator: 将快捷键对应到相应的菜单命令。它会把WM_KEYDOWN 或WM_SYSKEYDOWN转化成快捷键表中相应的WM_COMMAND 或WM_SYSCOMMAND 消息,然后把转化后的WM_COMMAND或WM_SYSCOMMAND直接发送到窗口过程处理,处理完后才会返回。

8(消息死锁( Message Deadlocks)

假设有线程A和B,现在有以下下步骤1) 线程A SendMessage给线程B, A等待消息在线程B中处理后返回2) 线程B收到了线程A发来的消息,并进行处理,在处理过程中,B也向线程A SendMessgae,然后等待从A返回。

因为此时,线程A正等待从线程B返回,无法处理B发来的消息,从而导致了\线程A,B相互等待,形成死锁。多个线程也可以形成环形死锁。

可以使用SendNotifyMessage或SendMessageTimeout来避免出现死锁。

9 BroadcastSystemMessage

我们一般所接触到的消息都是发送给窗口的,其实,消息的接收者可以是多种多样的,它可以是应用程序(applications), 可安装驱动(installable drivers), 网络设备(network drivers), 系统级设备驱动(system-level device drivers)等,BroadcastSystemMessage这个API可以对以上系统组件发送消息。

回调函数

对于很多初学者来说,往往觉得回调函数很神秘,很想知道回调函数的工作原理。本文将要解释什么是回调函数、它们有什么好处、为什么要使用它们等等问题,在开始之前,假设你已经熟知了函数指针。 什么是回调函数? 简而言之,回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用为调用它所指向的函数时,我们就说这是回调函数。 为什么要使用回调函数? 因为可以把调用者与被调用者分开。调用者不关心谁是被调用者,所有它需知道的,只是存在一个具有某种特定原型、某些限制条件(如返回值为int)的被调用函数。 如果想知道回调函数在实际中有什么作用,先假设有这样一种情况,我们要编写一个库,它提供了某些排序算法的实现,如冒泡排序、快速排序、shell排序、shake排序等等,但为使库更加通用,不想在函数中嵌入排序逻辑,而让使用者来实现相应的逻辑;或者,想让库可用于多种数据类型(int、float、string),此时,该怎么办呢?可以使用函数指针,并进行回调。 回调可用于通知机制,例如,有时要在程序中设置一个计时器,每到一定时间,程序会得到相应的通知,但通知机制的实现者对我们的程序一无所知。而此时,就需有一个特定原型的函数指针,用这个指针来进行回调,来通知我们的程序事件已经发生。实际上,SetTimer() API使用了一个回调函数来通知计时器,而且,万一没有提供回调函数,它还会把一个消息发往程序的消息队列。 另一个使用回调机制的API函数是EnumWindow(),它枚举屏幕上所有的顶层窗口,为每个窗口调用一个程序提供的函数,并传递窗口的处理程序。如果被调用者返回一个值,就继续进行迭代,否则,退出。EnumWindow()并不关心被调用者在何处,也不关心被调用者用它传递的处理程序做了什么,它只关心返回值,因为基于返回值,它将继续执行或退出。 不管怎么说,回调函数是继续自C语言的,因而,在C++中,应只在与C代码建立接口,或与已有的回调接口打交道时,才使用回调函数。除了上述情况,在C++中应使用虚拟方法或函数符(functor),而不是回调函数。 一个简单的回调函数实现 下面创建了一个sort.dll的动态链接库,它导出了一个名为CompareFunction的类型--typedef int (__stdcall *CompareFunction)(const byte*, const byte*),它就是回调函数的类型。另外,它也导出了两个方法:Bubblesort()和Quicksort(),这两个方法原型相同,但实现了不同的排序算法。

舆情信息处置机制制度精编版

舆情信息处置机制制度 为积极响应上级通知精神,进一步加强对舆情的引导与监控,建立健全舆情快速响应和处理机制,促进和保障幼儿园各项工作的有序开展,根据我园实际情况,采取以下措施:一、加强领导,构建全方位舆情监控网络 幼儿园舆情监控工作由保教处牵头,全面负责互联网及各大媒体的舆情引导与监控工作。设兼职舆情管理员一名,由保教主任担任。各部门、各年级组兼职舆情监督员,并邀请家委会主任担任社会舆情反馈员。进一步加强与地方各级新闻媒体的沟通协作,构建全方位舆情监控网络,密切配合,共同应对幼儿园舆情的引导与监控工作。 二、实行舆情监控巡查制度 1、实行舆情信息处置日值班制度,建立舆情信息处置每日记录。制定舆情监控负责制,每天由舆情监督员利用中午1点-2点,下午4点-5点两个时段负责监测跟踪网上涉及幼儿园工作的各种论坛、帖吧言论,掌握舆情热点,密切关注网络信息动态,捕捉带有苗头性、倾向性、群众性的问题。采取多种方式进行引导和疏通,并做好记录。 2、保教处舆情管理员每天向各处室了解一天舆情。 3、加强沟通,拓宽舆情监控渠道。加强与家委会负责人和地方其他媒体的沟通联系,及时了解来自各方面信息,及时扑捉舆情线索。

三、实行疏导、控制制度 每天舆情管理员整理舆情信息及时向园领导反馈情况,并对可能出现的突发事件进行早期预报,确保有关的重大舆情和负面信息早发现、早报告、早处置。对于有可能给幼儿园造成负面影响的舆论报道和评论,幼儿园组织协调有关力量及时进行舆情处置和舆论引导,有效疏导和控制负面舆情。 四、加强宣传,建立正确舆论导向 充分利用幼儿园网络、报纸、园信通等宣传平台,通过多种手段和渠道做正确的舆论方向引导,同时建立防控体系,积极消除不和谐、不稳定隐患。 化隆县第二幼儿园 2019年10月

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 派生的类,都可以接受此消息。

回调函数与回调机制

回调函数与回调机制 1. 什么是回调函数 回调函数(callback Function),顾名思义,用于回调的函数。回调函数只是一个功能片段,由用户按照回调函数调用约定来实现的一个函数。回调函数是一个工作流的一部分,由工作流来决定函数的调用(回调)时机。回调函数包含下面几个特性: ?属于工作流的一个部分; ?必须按照工作流指定的调用约定来申明(定义); ?他的调用时机由工作流决定,回调函数的实现者不能直接调用回调函数来实现工作流的功能; 2. 回调机制 回调机制是一种常见的设计模型,他把工作流内的某个功能,按照约定的接口暴露给外部使用者,为外部使用者提供数据,或要求外部使用者提供数据。 如上图所示,工作流提供了两个对外接口(获取参数、显示结果),以回调函数的形式实现。 ?“获取参数”回调函数,需要工作流使用者设定工作流计算需要的参数。 ?“显示结果”回调函数,提供计算结果给工作流使用者。

再以Windows的枚举顶级窗体为例。函数EnumWindows用于枚举当前系统中的所有顶级窗口,其函数原型为: BOOL EnumWindows( WNDENUMPROC lpEnumFunc, // callback function LPARAM lParam // application-defined value ); 其中lpEnumFunc是一个回调函数,他用于返回枚举过程中的获得的窗口的句柄。其定义约定为: BOOL CALLBACK EnumWindowsProc( HWND hwnd, // handle to parent window LPARAM lParam // application-defined value ); 在这个例子中,EnumWindows 是一个工作流,这个工作流用于遍历windows的所有窗口并获得其句柄。用户使用EnumWindows工作流的目的是想通过工作流来来获取窗口的句柄以便针对特定的一个或多个窗口进行相关处理。于是EnumWindows就扩展出接口lpEnumFunc,用于返回遍历的窗口句柄。 EnumWindows工作流的结束有两个方式:1,用户在回调函数中返回FALSE;2,再也找不到顶级窗口。我们可以推测EnumWindows的实现机制如下: 注:下列代码中的FindFirstTopWindows(), FindNextTopWindow()为假设的,Windows API 没有此函数,只是为了表明Enumwindows的内部流程。 BOOL EnumWindows( WNDENUMPROC lpEnumFunc, // callback function LPARAM lParam // application-defined value ) { BOOL bRet = TRUE; HWND hWnd = ::FindFirstTopWindows(); // 此函数是假设的,查找第一个顶级窗口 // 当hWnd为0时表示再也找不到顶级窗口 while( hWnd ) { bRet = (*lpEnumFunc)( hWnd, value ); if( !bRet) break; // 终止EnumWindows工作流; hWnd = ::FindNextWindow(); // 此函数是假设的,查找下一个顶级窗口 } } 在EnumWindows(...)函数中,实现了窗口枚举的工作流,他通过回调机制把用户关心(顶级窗口句柄)的和枚举工作流分开,用户不需要知道EnumWindows的具体实现,用户只要知道,设定了lpEnumFunc函数,然后把函数指针传给EnumWindwos就可以获得想要的窗口句柄。

hook的使用实例

在网上找了好久都没有找到消息hook的实例,下面是我的例子给大家分享一下 下面是dll中的代码: //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //我的经验,编译的时候会提示DllMain,已在DllMain.cpp中定义,把DllMain.cpp从源文件里删掉就好了 #include "stdafx.h" #include HHOOK hkey=NULL; HINSTANCE h_dll; #pragma data_seg(".MySec") //定义字段,段名.MySec HWND h_wnd=NULL; #pragma data_seg() #pragma comment(linker,"/section:.MySec,RWS") BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved) { h_dll=hinstDLL; // MessageBox(0,"运行dllman","",MB_OK); return TRUE; } LRESULT CALLBACK my_test(int nCode,WPARAM wParam,LPARAM iParam)// { /* if(nCode==HC_ACTION) { MessageBox(0,"成功!!","标题",MB_OK); } else { MessageBox(0,"失败!!","标题",MB_OK); } */ MessageBox(0,"被截取","",MB_OK); UnhookWindowsHookEx(hkey); return 1; } void SetHook(HWND hwnd) { h_wnd = hwnd; // MessageBox(0,"运行sethook","",MB_OK); hkey=SetWindowsHookEx(WH_KEYBOARD,my_test,h_dll,0); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 下面是EXE的代码:有很多头文件是没用上的,我个人习惯都带着- -,虽然这不是好习惯

校园网络舆情信息监测处置机制

校园网络舆情信息监测处置机制为进一步加强网络舆情监测,特别是加强校园网络舆情的引导和监控,防止不良信息对校园的侵害,掌握网络舆情主动权,加强对网络舆情的预警防范和监测引导,形成积极向上的主流舆论,营造良好的舆论环境,促进和保障校园网络信息服务健康、有序发展,根据国家有关法律法规,现结合我校实际情况,特制定本办法。 一、工作目标 加强网上舆情监控,及时掌握舆情动态,坚决封堵、删除各种有害信息,及时掌握学校学生在各种网络媒介中的言论和动态,加强正面引导,释疑解惑,化解矛盾,消除不良影响,营造积极、健康的舆论氛围。 二、主要内容 本办法中的网络舆情,特指可能或已经对学生思想政治教育工作产生影响的网上负面报道或网络负面言论。网络舆情的管理与处置,是指对涉及宣传思政工作的新闻报道或评论在互联网上刊发、扩散后,所引发的反应、言论、评论和后续报道等综合舆论情况的监测、控制和化解等具体措施。 三、组织结构 成立网络舆情管理与处置工作领导小组,指定教导处为领导小组办公室,在领导小组的领导下牵头开展网络舆情管 理与处置的组织、监督、实施、考核工作。

四、工作职责 网络舆情监督员负责监测学校的微博、微信,学生个人人人通、微博、微信的舆情情况,了解各网站当前的舆情,及时将舆情通报网络舆情管理员,督促及时控制和引导,并作好日志记录和备案工作;负责跟踪各单位的舆情控制及引导情况,及时上报学校。 五、工作原则 按照“谁主管、谁负责”的原则将监测到的舆情信息进行分转交办,按照“快速反应、确认事实、妥善处理”的原则及时对网络舆情进行分析、判断、评估,准确查找舆情信息产生的原因,认真核实舆情反映的问题,对舆情走向作出正确的判断,对舆情可能产生的影响进行客观、全面评估,及时准备好跟(回)帖材料。 在处置网络舆情事件时,一定要端正工作态度,多渠道、多方法全面了解事件真相,不推卸责任,勇于承担应负的责任;在回应时不要只站在如何消除对学校和学校形象的影响上,而要站在师生或受害者的立场上。第一时间告知学生和当事人事情真相,进行真诚、公开、及时的沟通,不使矛盾进一步激化,赢得学生的理解和信任。根据某一重大舆情事件的发展态势和走向,最大程度地争取媒介的公信力和权威性,适时转移目标,发布最及时权威的信息,左右网络舆情的走向,把噪音杂音压下来,使该网络舆情信息关注度逐渐转冷。要加强正面宣传,树立良好风气。 六、操作流程

Windows内存管理机制

Windows内存管理机制 在编程中,很多Windows或C++的内存函数不知道有什么区别,更别谈有效使用;根本的原因是,没有清楚的理解操作系统的内存管理机制,本文企图通过简单的总结描述,结合实例来阐明这个机制。 本文目的: 对Windows内存管理机制了解清楚,有效的利用C++内存函数管理和使用内存。 本文内容: 本文一共有六节,由于篇幅较多,故按节发表。其他章节请看本人博客的Windows内存管理及C++内存分配实例(一)(二)(三)(四)和(五)。 1. 进程地址空间 2.内存状态查询函数 3.内存管理机制--虚拟内存 (VM) 4.内存管理机制--内存映射文件 (Map) 5.内存管理机制--堆 (Heap) 使用场合 操作系统为每个线程都建立一个默认堆栈,大小为1M。这个堆栈是供函数调用时使用,线程内函数里的各种静态变量都是从这个默认堆栈里分配的。

堆栈结构 默认1M的线程堆栈空间的结构举例如下,其中,基地址为0x0004 0000,刚开始时,CPU的堆栈指针寄存器保存的是栈顶的第一个页面地址 0x0013 F000。第二页面为保护页面。这两页是已经分配物理存储器的可用页面。 随着函数的调用,系统将需要更多的页面,假设需要另外5页,则给这5页提交内存,删除原来页面的保护页面属性,最后一页赋予保护页面属性。 当分配倒数第二页0x0004 1000时,系统不再将保护属性赋予它,相反,它会产生堆栈溢出异常STATUS_STACK_OVERFLOW,如果程序没有处理它,则线程将退出。最后一页始终处于保留状态,也就是说可用堆栈数是没有1M的,之所以不用,是防止线程破坏栈底下面的内存(通过违规访问异常达到目的)。

MFC的运行机制和消息响应机制

MFC的类层次结构与运行机制 MFC的类层次结构 如图所示(子类指向父类): 其中: CObject:是MFC提供的绝大多数类的基类。该类完成动态空间的分配与回收,支持一般的诊断、出错信息处理和文档序列化等。 CCmdTarget:主要负责将系统事件(消息)和窗口事件(消息)发送给响应这些事件的对象,完成消息发送、等待和派遣调度等工作,实现应用程序的对象之间的协调运行。 CWinApp:是应用程序的主线程类,它是从CWinThread类派生而来的。CWinThread类用来完成对线程的控制,包括线程的创建、运行、终止和挂起等。 CDocument:是文档类,包含了应用程序在运行期间所用到的数据。 CWnd:是一个通用的窗口类,用来提供Windows中的所有通用特性、对话框和控件。 CFrameWnd是从CWnd类继承来的,并实现了标准的框架应用程序。 CDialog类用来控制对话框窗口。 CView:用于让用户通过窗口来访问文档。 CMDIFrameWnd和CMDIChildWnd:分别用于多文档应用程序的主框架窗口和文档子窗口的显示和管理。CMiniFrameWnd类是一种简化的框架窗口,它没有最大化和最小化窗口按钮,也没有窗口系统菜单,一般很少用到它。 MFC运行机制 在程序中,当定义一个类对象时,它会自动调用相应的构造函数。所谓"类对象",就是用该类定义的"变量",这个"变量"又称为类的一个实例。例如,theApp就是类CSimpApp的一个对象。 MFC正是利用类的这种"自动调用相应的构造函数"特性,使得WinMain()函数的调用变成了应用程序框架内部的调用,所以我们在代码中看不到每个Windows程序所必须有的WinMain()函数。 当应用程序运行到"CSimpApp theApp;"时,系统就会先调用基类CWinApp构造函数,进行一系列的内部初始化操作,然后自动调用CSimpApp的虚函数InitInstance(),该函数会进一步调用相应的函数来完成主窗口的构造和显示工作。下面来看看上述程序中InitInstance的执行过程。 首先执行的是: m_pMainWnd = new CMainFrame; 该语句用来创建从CFrameWnd类派生而来的用户框架窗口CMainFrame类对象,继而调用该类的构造函数,使得Create函数被调用,完成了窗口创建工作。

Handler消息处理机制

Handler消息处理机制 1.概述。 Handler消息处理机制对于初学者来说,应该算是一块心病,几乎每次面试都会被问到,今天我抽时间从源码的角度总结一下相关知识点。先看一下我们平时是怎么用的,如下代码实例: public class MainActivity extends AppCompatActivity { private TextView text; private Handler mHandler; int i=0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(https://www.doczj.com/doc/7316990165.html,yout.activity_main); text = (TextView) findViewById(R.id.text); mHandler = new Handler(){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); text.setText("变为:"+msg.what); } }; } public void sendMes(View view){ mHandler.sendEmptyMessage(i); i++; } } 很简单,onCreat()方法中实例化了一个Handler实例,实现其handlerMessage(Message msg)方法,在方法中改变TextView的显示内容,在布局文件中放了一个Button设置其android:onClick="sendMes",看一下效果:

Windows消息传递机制详解

用户是如何跟应用软件打交道的 我们来看看,用户究竟是如何与应用软件打交道的(用户不需要知道这个具体过程,但应用软件的开发人员必须知道),如下图所示: 从上图可以看到:在物理上,离用户最近的实际上是输入输出设备,下面我们看看上图中1-6这六个步骤分别表示什么意思(为了简便,在叙述时,我们的标号没有用圆圈): 1. 用户点击鼠标或者键盘; 2. Windows感觉到了鼠标或键盘的动作; 3. Windows把这个消息告诉应用程序; 4. 应用程序告诉Windows去做事,实际上就是应用程序调用Windows的API函数; 5. Windows让输出设备做事; 6. 用户获得输出。 对用户来说,没有必要了解输入输出设备和Windows的相关知识。对程序员(写应用程序的人)来说,没有必要了解输入输出设备,但是必须了解Windows的基本知识。在下面的叙述中,我们就不管输入输出设备了。

上面的过程还是很笼统,为了弄得更清楚,我们有必要了解Windows的消息机制,如图: 下面,我们来慢慢描述(上图中的虚线表示消息的流程): step0: 程序员编程,把WinMain函数和窗口回调函数写好; step1: Windows调用WinMain函数,启动应用程序,Windows会建立一个消息队列,用来存储消息。 step2: WinMain函数调用Windows的API函数,比如调用CreateWindow和ShowWindow, 从而生成并显示一个窗口。在调用CreateWindow函数时,会产生一个消息,这个消息并不进入消息队列,但窗口的回调函数仍然会处理,在此,我们不讨论非队列消息。 step3: WinMain函数调用Windows的API函数,比如调用GetMessage来从消息队列中取出消息。假设用户这个时候在窗口中点击鼠标,那么Windows会把这个事件包装成消息,投到消息队列中,GetMessage会取出这个消息,通过DispatchMessage送到Windows; step4: Windows进而会将该消息发送到窗口的回调函数,并对该函数进行调用; step5:窗口的回调函数可以对这个消息进行相应处理,这个处理的具体方法由程序员自己决定,通常是调用Windows的API函数来实现处理。

关于回调函数的几个例子(c)

以下是一个简单的例子。实现了一个repeat_three_times函数,可以把调用者传来的任何回调函数连续执行三次。 例 1. 回调函数 /* para_callback.h */ #ifndef PARA_CALLBACK_H #define PARA_CALLBACK_H typedef void (*callback_t)(void *); extern void repeat_three_times(callback_t, void *); #endif /* para_callback.c */ #include "para_callback.h" void repeat_three_times(callback_t f, void *para) { f(para); f(para); f(para); } /* main.c */ #include #include "para_callback.h" void say_hello(void *str) { printf("Hello %s\n", (const char *)str); } void count_numbers(void *num) { int i; for(i=1; i<=(int)num; i++) printf("%d ", i); putchar('\n');

} int main(void) { repeat_three_times(say_hello, "Guys"); repeat_three_times(count_numbers, (void *)4); return 0; } 回顾一下前面几节的例子,参数类型都是由实现者规定的。而本例中回调函数的参数按什么类型解释由调用者规定,对于实现者来说就是一个void *指针,实现者只负责将这个指针转交给回调函数,而不关心它到底指向什么数据类型。调用者知道自己传的参数是char *型的,那么在自己提供的回调函数中就应该知道参数要转换成char *型来解释。 回调函数的一个典型应用就是实现类似C++的泛型算法(Generics Algorithm)。下面实现的max函数可以在任意一组对象中找出最大值,可以是一组int、一组char或者一组结构体,但是实现者并不知道怎样去比较两个对象的大小,调用者需要提供一个做比较操作的回调函数。 例 2. 泛型算法 /* generics.h */ #ifndef GENERICS_H #define GENERICS_H typedef int (*cmp_t)(void *, void *); extern void *max(void *data[], int num, cmp_t cmp); #endif /* generics.c */ #include "generics.h" void *max(void *data[], int num, cmp_t cmp) { int i; void *temp = data[0];

OpenGL一个简单的例子

先编译运行一个简单的例子,这样我们可以有一个直观的印象。从这个例子我们可以看到OpenGL可以做什么,当然这个例子只做了很简单的一件事--绘制一个彩色的三角形。除此以外,我们还可以看到典型的OpenGL程序结构及openGL的运行顺序。 例1:本例在黑色的背景下绘制一个彩色的三角形,如图一所示。

图一:一个彩色的三角形首先创建工程,其步骤如下:

1)创建一个Win32 Console Application。 2)链接OpenGL libraries。在Visual C++中先单击Project,再单击Settings,再找到Link单击,最后在Object/library modules 的最前面加上OpenGL32.lib GLu32.lib GLaux.lib 3)单击Project Settings中的C/C++标签,将Preprocessor definitions 中的_CONSOLE改为__WINDOWS。最后单击OK。 现在你可以把下面的例子拷贝到工程中去,编译运行。你可以看到一个彩色的三角形。 我们先看看main函数。函数中以glut开头的函数都包含在glut.h中。GLUT库的函数主要执行如处理多窗口绘制、处理回调驱动事件、生成层叠式弹出菜单、绘制位图字体和笔画字体,以及各种窗口管理等任务。 ·glutInit用来初始化GLUT库并同窗口系统对话协商。 ·glutInitDisplayMode用来确定所创建窗口的显示模式。本例中的参数GLUT_SINGLE 指定单缓存窗口,这也是缺省模式,对应的模式为GLUT_DOUBLE 双缓存窗口。参数GLUT_RGB指定颜色RGBA模式,这也是缺省模式,对应的模式为GLUT_INDEX 颜色索引模式窗口。 ·glutInitWindowSize初始化窗口的大小,第一个参数为窗口的宽度,第二个参数为窗口的高度,以像素为单位。 ·glutInitWindowPosition设置初始窗口的位置,第一个参数为窗口左上角x的坐标,第二个参数为窗口左上角y的坐标,以像素为单位。屏幕的左上角的坐标为(0,0),横坐标向右逐渐增加,纵坐标向下逐渐增加。 ·glutCreateWindow创建顶层窗口,窗口的名字为扩号中的参数。 ·background() 这是自己写的函数,设置背景。其实这个函数中的语句可以写在display 函数中,但为了使功能块更加清晰,所以把背景这一部分单独提出来。 ·glutReshapeFunc注册当前窗口的形状变化回调函数。当改变窗口大小时,该窗口的形状改变回调函数将被调用。在此例中就是myReshape指定形状变化函数。 ·glutDisplayFunc注册当前窗口的显示回调函数。当一个窗口的图像层需要重新绘制时,GLUT将调用该窗口的的显示回调函数。在此例中的mydisplay就是显示回调函数,显示回调函数不带任何参数,它负责整个图像层的绘制。我们的大部分工作将集中在这个函数中。 ·glutMainLoop进入GLUT事件处理循环。glutMainLoop函数在GLUT程序中最多只能调用一次,它一旦被调用就不再返回,并且调用注册过的回调函数。所以这个函数必须放在注册回调函数的后面,此例中为glutReshapeFunc,glutDisplayFunc。

信息发布管理制度流程

信息发布管理制度 为使教育局门户网站和微信管理平台在信息化建设中发挥应有的作用,加强对网站的管理,保证其安全、有效、可靠地运行,依据国家有关法律、法规,并根据信息化建设的要求,结合我局实际,特制定本制度。 第一条门户网站发布信息实行信息审批制度,信息和相应的审批遵循“谁主管、谁负责;谁运营、谁办理”的原则。 第二条网站的信息发布由宣传科统一负责。局机关各科室及所属各单位负责提供本单位的相关信息,具体责任根据各单位工作职责划分。 第三条宣传科负责监督、审核网站内容。局机关各科室及所属各单位,所提供的内容需经本部门负责人批准后,交办公室或宣传科审核统一发布。相关我局重大新闻和重大事件的发布必须经办公室或宣传科主管领导审核后,请示分管局领导或局长,批准后方能正式发布。 第四条局机关办公室和宣传科对所有上传的涉及局新闻、政策、法规等重要信息负有责任;局机关各科室及所属各单位,对所提供的相关信息负有责任。 第五条网站上发布的信息必须符合国家有关保密规定,严禁涉密信息上网。各有关部门应制定上网信息发布审核管理制度,规范上网信息发布流程。一般情况下,拟上网发布的信息由拟稿人拟稿后须经科室初审、单位分管领导把关后方可发布,未经审核批准的信息不得上网。 第六条信息审核内容包括:上网信息有无涉密问题;上网信息目前对外发布是否适宜;信息中的数据是否准确;是否含有法律、行政法规禁止的内容等。上网信息出现安全问题的,要追究信息发布部门的责任。 第七条局机关各科室及所属各单位信息采集人员只能操作自己所负

责的相关业务内容,不得擅自修改、删除、发布其他采集人员所采集的信息。否则将追究信息采集人员和所在处室负责人的责任。 第八条局机关及所属各单位信息采集人员要严格遵守国家有关法律、行政法规,严格执行国家安全保密制度,不从事与身份不符的活动,各单位信息采集人员按照权限,采集自己所负责的相关栏目文档。 第九条局机关相关人员不得利用门户网站散布含有危害国家安全和社会稳定的信息,不得泄露国家秘密和工作秘密,不得宣扬暴力、色情等内容。网站的使用过程中,必须遵守网站各功能的使用说明和使用协议。 第十条 第十一条 第十二条 第十三条用户信息安全管理制度 网站为充分保护用户的个人隐私、保障用户信息安全,特制订用户信息安全管理制度。 1、尊重并保护用户的个人隐私,除了在与用户签署的隐私保护协议和网站服务条款以及其他公布的准则规定的情况下,未经用户授权不随意公布和泄露用户个人身份信息。 2、定期对相关人员进行网络信息安全培训并进行考核,使网站相关管理人员充分认识到网络安全的重要性,严格遵守相应规章制度。。 3、对用户的个人信息严格保密,并承诺未经用户授权,不得编辑或透露其个人信息及保存在本系统中的非公开内容,但下列情况除外: 4、①违反相关法律法规或本网站服务协议规定; 5、②按照主管部门的要求,有必要向相关法律部门提供备案的内容; 6、③因维护社会个体和公众的权利、财产或人身安全的需要;

Windows端口异常占用的处理

Windows端口异常占用的处理 【来源:小鸟云计算】 Ps.小鸟云,国内专业的云计算服务商 问题现象 服务器应用使用的端口被异常占用导致服务启动失败,例如:Windows上安装的Tomcat 无法启动,TCP 80端口已经被其它应用占用。 问题原因 应用程序需要使用的TCP/UDP端口被其它程序、或者病毒木马占用。 排查方法 使用netstat -ano命令可以找出占用端口的进程ID,而后使用tasklist /svc命令找出对应的进程。 如下给出一例安装Tomcat后,启动Tomcat提示端口被占用的处理过程。 1.使用netstat -ano |find ":80" 看到占用端口的进程ID是4,注:请根据实际情况修改端口 2.使用tasklist /svc| find "4" 看到是系统进程。注:请根据实际情况修改进程ID

3.尝试关闭了IIS ,iisreset /stop 4.但是发现80端口仍然被占用。于是使用curl -I 127.0.0.1 查看返回的server是Microsoft-HTTPAPI/2.0 而不是Server: Microsoft-IIS/7.5 能够使用Microsoft-HTTPAPI/2.0的只能是微软的产品。检查是否有安装SQL SERVER ,如果有尝试关闭SQL Server Reporting Service这个服务。 关闭后再使用curl -I 127.0.0.1 就提示80端口无法连接,说明端口已经被释放。 注意:如果没有安装curl还可以使用telnet 127.0.0.1 80 执行完,ctrl+c终止就会出现下面图片的样子,也可以看到server:Microsoft-HTTPAPI/2.0 ,当然仅靠这个是不能判断

Windows事件驱动机制-1

Windows的事件驱动机制 在Windosw系统中,程序的设计围绕事件驱动来进行。当对象有相关的事件发生时(如按下鼠标键),对象产生一条特定的标识事件发生的消息,消息被送入消息队列,或不进入队列而直接发送给处理对象,主程序负责组织消息队列,将消息发 送给相应的处理程序,使相应的处理程序执行相应的动作,做完相应的处理后将控制权交还给主程序。 在这种机制中,对象的请求仅仅是向队列中添加相应的消息,耗时的处理则被分离给处理函数。这种结构的程序中各功能模块界限分明,便于扩充,能充分利用CPU 的处理能力,使系统对外界响应准确而及时。 Windows事件驱动机制 我们当中不少使用VC、Delphi等作为开发语言的程序员是一步步从DOS 下的Basic、C++中走过来的,而且大多在刚开始学习编程时也是先从DOS下的编程环境入手的,因此在习惯了DOS下的过程驱动形式的顺序程序设计方法后,往往在向Windows下的开发环境转型的过程中会对Windows所采取的事件驱动方式感到无法适应。因为DOS和Windows这两种操作系统的运行机制是截然不同的,DOS下的任何程序都是使用顺序的、过程驱动的程序设计方法。这种程序都有一个明显的开始、明显的过程以及一个明显的结束,因此通过程序就能直接控制程序事件或过程的全部顺序。即使是在处理异常时,处理过程也仍然是顺序的、过程驱动的结构。而Windows的驱动方式则是事件驱动的,即程序的流程不是由事件的顺序来控制,而是由事件的发生来控制,所有的事件是无序的,所为一个程序员,在编写程序时,并不知道用户会先按下哪个按纽,也就不知道程序先触发哪个消息。因此我们的主要任务就是对正在开发的应用程序要发出的或要接收的消息进行排序和管理。事件驱动程序设计是密切围绕消息的产生与处理而展开的,一条消息是关于发生的事件的消息。 Windows的消息循环 Windows操作系统为每一个正在运行的应用程序保持有一个消息队列。当有事件发生后,Windows并不是将这个激发事件直接送给应用程序,而是先将其翻译成一个Windows消息,然后再把这个消息加入到这个应用程序的消息队列中去。应用程序需要通过消息循环来接收这些消息。在MFC中使用了对WinAPI进行了很好封装的类库,虽然可以为编程提供一个面向对象的界面,使Windows程序员能够以面象对象的方式进行编程,把那些进行SDK编程时最

回调函数的概念及其使用

回调函数的概念及其使用

回调函数的概念及其使用 1 什么是回调 软件模块之间总是存在着一定的接口,从调用方式上,可以把他们分为三类:同步调用、回调和异步调用。同步调用是一种阻塞式调用,调用方要等待对方执行完毕才返回,它是一种单向调用;回调是一种双向调用模式,也就是说,被调用方在接口被调用时也会调用对方的接口;异步调用是一种类似消息或事件的机制,不过它的调用方向刚好相反,接口的服务在收到某种讯息或发生某种事件时,会主动通知客户方(即调用客户方的接口)。回调和异步调用的关系非常紧密,通常我们使用回调来实现异步消息的注册,通过异步调用来实现消息的通知。同步调用是三者当中最简单的,而回调又常常是异步调用的基础,因此,下面我们着重讨论回调机制在不同软件架构中的实现。 对于不同类型的语言(如结构化语言和对象语言)、平台(Win32、JDK)或构架(CORBA、DCOM、WebService),客户和服务的交互除了同步方式以外,都需要具备一定的异步通知机制,让服务方(或接口提供方)在某些情况下能够主动通知客户,而回调是实现异步的一个最简捷的途径。 对于一般的结构化语言,可以通过回调函数来实现回调。回调函数也是一个函数或过程,不过它是一个由调用方自己实现,供被调用方使用的特殊函数。

在面向对象的语言中,回调则是通过接口或抽象类来实现的,我们把实现这种接口的类成为回调类,回调类的对象成为回调对象。对于象C++或Object Pascal 这些兼容了过程特性的对象语言,不仅提供了回调对象、回调方法等特性,也能兼容过程语言的回调函数机制。 Windows平台的消息机制也可以看作是回调的一种应用,我们通过系统提供的接口注册消息处理函数(即回调函数),从而实现接收、处理消息的目的。由于Windows平台的API是用C语言来构建的,我们可以认为它也是回调函数的一个特例。 对于分布式组件代理体系CORBA,异步处理有多种方式,如回调、事件服务、通知服务等。事件服务和通知服务是CORBA用来处理异步消息的标准服务,他们主要负责消息的处理、派发、维护等工作。对一些简单的异步处理过程,我们可以通过回调机制来实现。 下面我们集中比较具有代表性的语言(C、Object Pascal)和架构(CORBA)来分析回调的实现方式、具体作用等。 2 过程语言中的回调(C) 2.1 函数指针 回调在C语言中是通过函数指针来实现的,通过将回调函数的地址传给被调函数从而实现回调。因此,要实现回调,必须首先定义函数指针,请看下面的例子: void Func(char *s);// 函数原型 void (*pFunc) (char *);//函数指针 可以看出,函数的定义和函数指针的定义非常类似。 一般的化,为了简化函数指针类型的变量定义,提高程序的可读性,我们需要把函数指针类型自定义一下。 typedef void(*pcb)(char *); 回调函数可以象普通函数一样被程序调用,但是只有它被当作参数传递给被调函数时才能称作回调函数。 被调函数的例子:

回调函数实现dll向主程序传递数据

回调函数实现dll向主程序传递数据 用dll封装窗口主要是封装对话框。软件开发中经常要使用的一个功能是导入数据,且要求可视化操作,如为对应的变量选择对应的列,设置数据的起始和终止行等。希望将界面做成如下形式: 由于这个界面和数据导入的通用性,我们希望将其封装到dll,提供一些接口进行窗口显示和数据传递就可以了。但是我们遇到一个问题:这里的数据传递我们希望是在点击OK之后获取对话框也就是dll中的数据传递到主程序,而在主程序中我们装载dll的函数是一个顺序的执行过程,不能进行消息响应。因此我们想到了使用回调函数。在这里的具体思想就是:在点dll的时候,我们使用回调函数将数据传到主程序,调用主程序的函数进行处理。虽然这样的过程有些打乱程序的执行顺序,但是可以到达我们的目的。下面介绍实现过程: 1、我们建立一个MFC的规则dll将写好的导入数据的对话框代码进行复制, 封装dll。 2、除了导出读取数据和显示对话框的函数之外,导出一个传递函数(回调 函数)形参的函数,这里我们采用一个在一个h文件中定义导出函数, 并利用宏切换功能,实现dll和主程序包含同一个h文件就可以实现函数 的导出和导入。具体代码见程序实例中的DllExport.h 3、具体介绍使用回调函数传递数据功能的实现。在DllExport.h中声明一个 函数的指针 typedef void (* pFunc)(double **pdata,int* nConut); 其中的两个参数pdata和nCount分别为我们要传递数据(一个二维数组)的指针,和一共有多少行数据。 接着声明一个以这个函数指针为形参的导出函数:

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