吉林大学远程教育课件 Windows A P I编 程 (第四十五讲) 主讲人 : 翟慧杰 学 时:48.

Slides:



Advertisements
Similar presentations
软件开发技术基础 第 3 章 操作系统及程序设计 讲授教师:卫颜俊. 主 要 内 容 主 要 内 容 操作系统及其功能 进程管理应用程序设计 内存管理应用程序设计 设备与文件管理应用程序设计 人机接口管理应用程序设计.
Advertisements

现代电子技术实验 ——综合实验之单片机部分
C语言程序设计 主讲教师 :张群燕 电话:
第4章 條件判斷與迴圈 Java 2 程式設計入門與應用.
迴圈 迴圈基本觀念 while迴圈 do 迴圈 for迴圈 巢狀迴圈 迴圈設計注意事項 其他控制指令 迴圈與選擇的組合.
C#程序设计案例教程 第3章 程 序 结 构.
第一章 C语言概述 计算机公共教学部.
AI人工智慧報告 黑白棋 班級:資工四乙 學號:498G0009 姓名:盧冠妤.
南京理工大学 第2章 Java基本语法 本章我们将学习Java编程语言的基本语法,包括变量、操作符、表达式、语句、字符串、数组、控制流以及如何使用帮助文档。 使用下面的编程框架: public class Test{ public static void main(String []args){ //以下添加测试代码.
第 5 章 流程控制 (一): 條件分支.
计算机图形学 授课教师:陈荣钦 短号: 单位:数信学院.
第二章 JAVA语言基础.
選擇 運算式 邏輯運算 if指令 流程圖基本觀念 程式註解 巢狀if指令 switch指令.
第三章 控制结构.
CH2 開發環境介紹 最簡單的互動設計 – Arduino一試就上手 孫駿榮、吳明展、盧聰勇.
Class 2 流程控制-選擇敘述與迴圈.
第二十九章 DLL / LIB函式庫開發 當我們開發程式到一個階段之後,我們一定會希望各個Component的程式碼可以分開的越清楚越好。而這一章最主要就是要告訴各位讀者,我們常在Windows系統中看到的dll或是lib的檔案該怎麼實作?做出這樣的library我們又該如何運用?為什麼使用dll或是lib有利於我們開發程式?以上這些疑問都將會在這一章中得到解答。
第二章 C# 基础知识.
佇列 (Queue).
C++Primer 3rd edition 中文版 Chap 5
第3章 C 語言的基本知識.
第4讲 Windows编程基础 此为封面页,需列出课程编码、课程名称和课程开发室名称。
授课老师:龚涛 信息科学与技术学院 2018年3月 教材: 《Visual C++程序员成长攻略》 《C++ Builder程序员成长攻略》
2 C++ 的基本語法和使用環境 親自撰寫和執行程式是學好程式語言的不二法門。本章藉由兩個簡單的程式,介紹C++ 程式的基本結構和開發環境,讓初學者能逐漸建立使用C++ 的信心。
简要回顾 了解课程体系、课程目的和主要内容 掌握Windows编程涉及的一些主要概念 DOS程序和Windows程序的主要区别 窗口和程序
第1章 Windows应用程序框架的 创建与消息处理
PHP 程式流程控制結構.
第3章 Windows 应用程序基础 2018/12/6 第2讲 Windows 应用程序基础 VC++面向对象与可视化程序设计.
网络游戏开发语言基础 ——Windows程序设计
第5章 堆疊(Stacks) 5-1 堆疊的基礎 5-2 堆疊的表示法 5-3 堆疊的應用 - 運算式的計算與轉換
第7章 编译预处理 本章要求: 本章重点: 本章难点: 掌握用#define定义无参数宏和带有参数宏定义和调用方法;
變數命名 保留字(Reserved Word)
Windows 编程技术 2005年9月 2018/12/31.
第4章 MFC编程 4.1 MFC概述 4.2 MFC和Win CObject类 4.4 消息映射的实现
任务九 基于BasicRF的无线传感网络应用
2019/1/17 Java语言程序设计-程序流程 教师:段鹏飞.
C++语言程序设计 第二章 C++简单程序设计.
計數式重複敘述 for 迴圈 P
授课老师:龚涛 信息科学与技术学院 2016年3月 教材:《Visual C++程序员成长攻略》 《C++ Builder程序员成长攻略》
第三章 C# 基础知识.
第1章 概述 本章要点: C语言程序结构和特点 C语言程序的基本符号与关键字 C语言程序的编辑及运行 学习方法建议:
版权所有 复制必究 第 6 章 MFC原理与方法.
软件测试 (四)静态测试与动态测试.
程式結構&語法.
4 條件選擇 4.1 程式基本結構 循序式結構 選擇式結構 重複式結構 4-3
函式庫補充資料.
程式的時間與空間 Time and Space in Programming
第十四章 若干深入问题和C独有的特性 作业: 函数指针 函数作参数 函数副作用 运算 语句 位段 存储类别 编译预处理
第5章 文本与字体 2019/4/25 面向对象与可视化 程序设计 --Visual C++ 编程 主讲教师: 唐 龙教授 (计算机科学与技术系) 黄维通博士 (计算机与信息管理中心) 清 华 大 学 2001年2月 2019/4/25 Huang Weitong.
<编程达人入门课程> 本节内容 为什么要使用变量? 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ:
第二章 Java语法基础.
第二章 类型、对象、运算符和表达式.
目标 流程控制 字符串处理 C# 的类和对象 C# 访问修饰符 C# 构造函数和析构函数.
第10章媒体控制接口 10.1 MCI设备类型 10.2 MCI编程步骤 10.3使用MCIWnd窗口类.
#include <iostream.h>
第二章 Java基本语法 讲师:复凡.
第五章 逻辑运算和判断选取控制 §5.1 关系运算符和关系表达式
PHP程式設計 五、程式流程控制結構 建國科技大學 資訊管理學系 饒瑞佶.
第1章 数据结构基础概论 本章主要介绍以下内容 数据结构研究的主要内容 数据结构中涉及的基本概念 算法的概念、描述方法以及评价标准.
1.4WIN32中的宽字符.
_01自己实现简单的消息处理框架模型 本节课讲师——void* 视频提供:昆山爱达人信息技术有限公司
单片机应用技术 (C语言版) 第4章 C51程序设计入门
第2章 Java语言基础.
多重條件選擇敘述
104 四技二專甄選入學 簡章解析 輔導室 何乙娟.
第三章 流程控制 程序的运行流程 选择结构语句 循环结构语句 主讲:李祥 时间:2015年10月.
第二章 Java基础语法 北京传智播客教育
第二章 Java基本语法 讲师:复凡.
函式庫補充資料 1.
隨機函數.
Presentation transcript:

吉林大学远程教育课件 Windows A P I编 程 (第四十五讲) 主讲人 : 翟慧杰 学 时:48

函数 BroadcastTransaction是一个自定义的函数,在例13-2中的具体定义如下:

在上述程序段中,函数DdeQueryNextServer用于获得连接列表中的下一个连接句柄。其函数原型定义如下:

如果函数 DdeQueryNextServer返回值不为空,则程序将进入一个 while循环,在 while循环体中定义了一个计数器,用于记录服务器的个数。同时循环体通过函数DdeClientTransaction来开始一个客户事务处理, DdeClientTransaction函数的原型定义如下:

如果服务器不能对客户方的事务进行处理,程序中通过调用函数 DdeAbandonTransaction放弃事务处理并回收所有的资源。函数DdeAbandonTransaction的原型定义如下: 在主窗口的消息处理函数MainwindProc中,处理WM_TIMER消息时还用到了一个DdePostAdvise函数,这个函数将使系统发送一条XTYP_ADVREQ消息给DDE回调函数,DdePostAdvise函数的原型定义如下:

例13-2的核心是 DDE回调函数,本例中定义的回调函数如下:

回调函数参数表中的wType参数用于指定回调类型;hszTopic参数用于指定主题名:参数hszItem比m用于指定主题中的某一项的名称。不难看出,上面的回调函数和消息处理函数有几分相似。 当服务器处理完XTYP_CONNECT事务并返回TRUE时,DDE会话也就开始了。服务器和客户之间的通信实际上都是借助上述的事务类型来实现的。当客户向服务器发送一个请求时,DDE管理库就会用相应的事务类型调用服务器的回调函数。 回调函数接收的事务确定于应用程序在DdeInitialize中指定的回调过滤标志,以及应用程序是否是客户或服务器,还是二者兼是。DDE事务类型如表 13-2所示。

例13-2的源程序 #include <windows.h> #include <ddeml.h> #include <stdlib.h> #include <string.h> #ifdef UNICODE #define STRICMP wcsicmp #define ITOA(c, sz, b) (itoa(sizeof(szA), szA, b), mbstowcs(sz, szA, b), sz) #else #define STRICMP stricmp #define ITOA itoa #endif //函数声明 HDDEDATA CALLBACK DdeCallback(WORD wType, WORD wFmt, HCONV hConv, HSZ hszTopic, HSZ hszItem, HDDEDATA hData, DWORD lData1, DWORD lData2);

VOID PaintDemo(HWND hwnd); LONG APIENTRY MainWndProc(HWND hwnd, UINT message, WPARAM wParam, LONG lParam); VOID BroadcastTransaction(PBYTE pSrc,DWORD cbData,UINT fmt,UINT xtyp); #define BASE_TIMEOUT 100 BOOL fActive; //标识数据是否正在被改变 DWORD idInst = 0; // DDEML对象 HANDLE hInst; //应用程序句柄 HCONVLIST hConvList = 0; //连接列表 HSZ hszAppName = 0; //应用程序名 HWND hwndMain; //主窗口句柄 TCHAR szT[20]; //用于重绘的静态缓冲区句柄 #ifdef UNICODE CHAR szA[20]; //用于UNICODE 转化缓冲区 TCHAR szTitle[] = TEXT("DDEmo (U)"); #else TCHAR szTitle[] = TEXT("DDEmo"); #endif

TCHAR szApp[] = TEXT("DDEmo"); // DDE服务名 TCHAR szPause[] = TEXT("PAUSE"); // DDE可执行命令 TCHAR szResume[] = TEXT("RESUME");// DDE可执行命令 UINT OurFormat; //定制的格式 int InCount = 0; //输入数据缓冲区 int cConvs = 0; // 激活的conversations数 int count = 0; //输出数据 int cyText, cxText, cyTitle; //重绘区域 //函数:WinMain //作用:程序入口 int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,INT nCmdShow) { MSG msg; WNDCLASS wc; TEXTMETRIC metrics; HDC hdc;

//窗口初始化 wc.style = 0; wc.lpfnWndProc = MainWndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = NULL; wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = NULL; wc.lpszMenuName = NULL; wc.lpszClassName = szTitle; if (!RegisterClass(&wc)) return(FALSE); //DDE初始化 if (DdeInitialize(&idInst, (PFNCALLBACK)MakeProcInstance((FARPROC)DdeCallback, hInstance), APPCMD_FILTERINITS |CBF_SKIP_CONNECT_CONFIRMS |CBF_FAIL_SELFCONNECTIONS |CBF_FAIL_POKES,0))

hwndMain = CreateWindow( szTitle, szTitle, hInst = hInstance; //创建窗口 hwndMain = CreateWindow( szTitle, szTitle, WS_CAPTION | WS_BORDER | WS_SYSMENU, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, NULL, NULL, hInstance, NULL); if (!hwndMain) { DdeUninitialize(idInst);//结束DDE return(FALSE); } hdc = GetDC(hwndMain); GetTextMetrics(hdc, &metrics);//获取当前所用字体 cyText = metrics.tmHeight + metrics.tmExternalLeading; cxText = metrics.tmMaxCharWidth * 8; cyTitle = GetSystemMetrics(SM_CYCAPTION); ReleaseDC(hwndMain, hdc);

//创建字符串句柄 hszAppName = DdeCreateStringHandle(idInst, szApp, 0); //注册自定义数据格式 OurFormat = RegisterClipboardFormat(szApp); //注册服务器名 DdeNameService(idInst, hszAppName, 0, DNS_REGISTER); //建立DDE会话列表 hConvList = DdeConnectList(idInst, hszAppName, hszAppName, hConvList, NULL); //向所有的服务器广播事务 BroadcastTransaction(NULL, 0, OurFormat, XTYP_ADVSTART); SetWindowPos(hwndMain, 0, 0, 0, cxText, (cyText * (cConvs + 1)) + cyTitle, SWP_NOMOVE | SWP_NOZORDER); ShowWindow(hwndMain, nCmdShow); UpdateWindow(hwndMain); //消息循环

while (GetMessage(&msg, 0, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } DestroyWindow(hwndMain); UnregisterClass(szTitle, hInstance); return(FALSE); //函数:BroadcastTransaction //作用:向所有服务器广播客户的事务请求 VOID BroadcastTransaction(PBYTE pSrc,DWORD cbData,UINT fmt,UINT xtyp) { HCONV hConv; DWORD dwResult; int cConvsOrg; cConvsOrg = cConvs; cConvs = 0; //初始化连接数为0 if (hConvList)

{ //下一个会话句柄 hConv = DdeQueryNextServer(hConvList, 0); while (hConv) { cConvs++; //处理客户事务 if (DdeClientTransaction(pSrc, cbData, hConv, hszAppName, fmt, xtyp, TIMEOUT_ASYNC, &dwResult)) //放弃客户事务 DdeAbandonTransaction(idInst, hConv, dwResult); } hConv = DdeQueryNextServer(hConvList, hConv); if (cConvs != cConvsOrg)

{//重绘窗口 InvalidateRect(hwndMain, NULL, TRUE); } //函数:MyProcessKey //作用:处理键盘消息 VOID MyProcessKey(TCHAR tchCode,LONG lKeyData) { switch (tchCode)

case TEXT('B'): case TEXT('b'): *((PBYTE)(-1)) = 0; break;}} //函数:MainWndProc //作用:主窗口消息循环 LONG APIENTRY MainWndProc(HWND hwnd,UINT message,WPARAM wParam,LONG lParam) { RECT rc; switch (message) {

case WM_CREATE://创建窗口 fActive = FALSE; break; case WM_RBUTTONDOWN: //按下鼠标右键 if (GetKeyState(VK_CONTROL) & 0x8000) //判断控制键的状态 {

//广播事务处理 BroadcastTransaction((PBYTE)szPause, sizeof(szPause), 0, XTYP_EXECUTE); MessageBeep(0); } KillTimer(hwndMain, 1);//销毁定时器 fActive = FALSE; InvalidateRect(hwnd, NULL, TRUE);//重绘窗口 UpdateWindow(hwnd); break; case WM_LBUTTONDOWN: //按下鼠标左键 if (GetKeyState(VK_CONTROL) & 0x8000) //判断控制键状态 { BroadcastTransaction((PBYTE)szResume, sizeof(szResume), 0, XTYP_EXECUTE); MessageBeep(0); //发出蜂鸣声

//设置定时器 SetTimer(hwndMain, 1, BASE_TIMEOUT + (rand() & 0xff), NULL); fActive = TRUE; InvalidateRect(hwnd, NULL, TRUE);//重绘窗口 UpdateWindow(hwnd); break; case WM_CHAR://键盘消息 MyProcessKey((TCHAR)wParam, lParam); case WM_TIMER://定时器消息 count++; //发送XTYP_ADVREQ事务给服务器的回调函数 DdePostAdvise(idInst, hszAppName, hszAppName); SetRect(&rc, 0, 0, cxText, cyText); InvalidateRect(hwndMain, &rc, TRUE);//重绘窗口 UpdateWindow(hwndMain);

case WM_PAINT://绘制窗口 PaintDemo(hwnd); break; case WM_CLOSE://结束应用程序 KillTimer(hwnd, 1); DdeDisconnectList(hConvList);//断开DDE会话 //撤消已注册的服务器名 DdeNameService(idInst, 0, 0, DNS_UNREGISTER); //销毁字符串句柄 DdeFreeStringHandle(idInst, hszAppName); DdeUninitialize(idInst);//结束DDE会话 PostQuitMessage(0); default://其他消息 return (DefWindowProc(hwnd, message, wParam, lParam)); } return(0);

//函数:PaintDemo //作用:绘制窗口 VOID PaintDemo(HWND hwnd) { PAINTSTRUCT ps; RECT rc; HCONV hConv; CONVINFO ci; int cConvsOrg = cConvs; BeginPaint(hwnd, &ps);//开始绘制 SetRect(&rc, 0, 0, cxText, cyText);//设定矩形区域 SetBkMode(ps.hdc, TRANSPARENT);//设置背景模式 SetTextColor(ps.hdc, 0x00FFFFFF); //文本颜色为白色 //填充矩形区域 FillRect(ps.hdc, &rc, (HBRUSH)GetStockObject(fActive ? BLACK_BRUSH : GRAY_BRUSH));

//输出文本 DrawText(ps.hdc, ITOA(count, szT, 10), -1, &rc, DT_CENTER | DT_VCENTER); if (hConvList) { OffsetRect(&rc, 0, cyText); SetTextColor(ps.hdc, 0); //设定文本颜色为黑色 cConvs = 0; //查询下一个服务器 hConv = DdeQueryNextServer(hConvList, 0); while (hConv) cConvs++; ci.cb = sizeof(CONVINFO); //获取DDE会话信息 DdeQueryConvInfo(hConv, QID_SYNC, &ci); FillRect(ps.hdc,&rc, (HBRUSH)GetStockObject(WHITE_BRUSH)); // 例13-2的源程序色背景

//输出文本 DrawText(ps.hdc, ITOA(ci.hUser, szT, 10), -1, &rc,DT_CENTER | DT_VCENTER); OffsetRect(&rc, 0, cyText); hConv = DdeQueryNextServer(hConvList, hConv); } EndPaint(hwnd, &ps);//结束绘制 if (cConvsOrg != cConvs) { SetWindowPos(hwndMain, 0, 0, 0, cxText, (cyText * (cConvs + 1)) + cyTitle,SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE); //函数:DdeCallback //作用:DDE回调函数

HDDEDATA CALLBACK DdeCallback(WORD wType,WORD wFmt,HCONV hConv,HSZ hszTopic,HSZ hszItem,HDDEDATA hData,DWORD lData1,DWORD lData2) {LPTSTR pszExec; switch (wType) { case XTYP_CONNECT://处理XTYP_CONNECT事务 return((HDDEDATA)TRUE); case XTYP_ADVREQ: case XTYP_REQUEST: //创建数据句柄 return(DdeCreateDataHandle(idInst,(PBYTE)&count, sizeof(count), 0, hszAppName, OurFormat, 0)); case XTYP_ADVSTART: return(HDDEDATA) ((UINT)wFmt == OurFormat && hszItem == hszAppName); case XTYP_ADVDATA: if (DdeGetData(hData, (PBYTE)&InCount, sizeof(InCount), 0)) {

//设置用户句柄 DdeSetUserHandle(hConv, QID_SYNC, InCount); } InvalidateRect(hwndMain, NULL, TRUE); return((HDDEDATA)DDE_FACK); case XTYP_EXECUTE: //访问DDE数据 pszExec = (LPTSTR)DdeAccessData(hData, NULL); if (pszExec) { if (fActive && !STRICMP(szPause, pszExec)) //消息定时器 KillTimer(hwndMain, 1); fActive = FALSE; UpdateWindow(hwndMain);

else if (!fActive && !STRICMP(szResume, pszExec)) { //设定定时器 SetTimer(hwndMain, 1, BASE_TIMEOUT + (rand() & 0xff), NULL); fActive = TRUE; InvalidateRect(hwndMain, NULL, TRUE); UpdateWindow(hwndMain); } MessageBeep(0); break; case XTYP_DISCONNECT: case XTYP_REGISTER:

//向服务器广播事务 BroadcastTransaction( NULL, 0, OurFormat, XTYP_ADVSTOP ); hConvList = DdeConnectList(idInst, hszItem, hszAppName, hConvList, NULL); BroadcastTransaction(NULL, 0, OurFormat, XTYP_ADVSTART); SetWindowPos(hwndMain, 0, 0, 0, cxText,(cyText * (cConvs + 1)) + cyTitle, SWP_NOMOVE | SWP_NOZORDER); UpdateWindow(hwndMain); return((HDDEDATA)TRUE); }return(0); }

例13-2的执行结果如图13-2所示。

13.3对象链接与嵌入基础知识 对象链接与嵌入实际上包括链接和嵌入对象、观察对象和编辑对象等涉及的所有技术。 11.3.1对象链接与嵌入 在这里一个对象被定义为任何一个文本中显示的并且可以被最终用户修改的数据。对象范围可从小到一个电子表格单元大到一个完整的文本,当一个对象归属于一个文本时,它与创建它的应用程序保持着一种联系。当一个对象被嵌入到其他对象之中时,不仅相关的数据被嵌入,而且相应的数据规则也被嵌入,这样用户不必返回该源应用程序就可以对一个对象进行编辑和修改。 当一个OLE文本包含了以各种不同格式表示的数据时,它就被称为一个复合文本。如果没有实现OLE技术,则每一种不同的数据类型都能够被最终用户修改。最终用户不得不在不同的应用程序中取得不同的编辑工具;如果应用程序实现了OLE技术,在同一环境下就可以实现对不同格式的数据进行编辑和修改。OLE技术给予了最终用户一个以文本为中心的参照框架系统,而不是一个以应用程序为中心的参照框架系统。

复合文本使用应用程序的许多特性来修改包含在其中的数据类型,任何一种数据均可以包含在一个复合文本之中。最终用户可以不必知道哪些数据格式与其他的数据格式相兼容,最终用户也不必知道怎样寻找创建该数据的其他应用程序。当用户在一个文本的一个部分里工作时,负责那个部分的应用程序合自动地开始工作。 OLE的好处在于: .文件的链接对象可以动态地加以改变; .当前的应用程序可以对未来的数据格式进行扩展,因为一个对 象的内容与包含它的文本无关; .文本文件可以更加紧凑,这是因为对一个对象的链接使得该文 本使用了该对象, 而不必存储该对象的数据; .一个应用程序可以很好地、专业化地做某项工作; .最终用户面向的是~个以文本为中心的用户系统; .实现了OLE协议就可以利用多种多样不同类型的对象优点。