博文

让对话框对UPDATE_COMMAND_UI生效(2007-04-24 12:05:00)

摘要:问题:一般情况下我们用UPDATE_COMMAND_UI来修改菜单的状态(enable/disable, check/uncheck, change text),但这个方法在一个基于对话框上的菜单却没有效果。
void CTestDlg::OnUpdateFileExit(CCmdUI* pCmdUI)
{
     pCmdUI->Enable(FALSE);
     pCmdUI->SetCheck(TRUE);
     pCmdUI->SetRadio(TRUE);
     pCmdUI->SetText("Close");
//以上方法在MDI、SDI程序中都能起作用,在对话框中却没有效果,根本没有调用这个函数。
}
 
原因分析:当显示一个下拉的菜单的时候,在显示菜单前会发送WM_INITMENUPOPUP消息。而CFrameWnd::OnInitMenuPopup函数会刷新这个菜单项,同时如果有UPDATE_COMMAND_UI响应函数,则调用它。通过它来更新反应每个菜单的外观效果(enabled/disabled, checked/unchecked).
在一个基于对话框的程序中,因为没有OnInitMenuPopup函数,所以不会调用UPDATE_COMMAND_UI响应函数,而是使用了CWnd类的默认处理, 这种处理没有调用UPDATE_COMMAND_UI响应函数。 解决方法如下:
第一步:
在对话框类的.cpp文件,添加一个ON_WM_INITMENUPOPUP入口到消息映射里面
BEGIN_MESSAGE_MAP(CTestDlg, CDialog)
//}}AFX_MSG_MAP
ON_WM_INITMENUPOPUP()
END_MESSAGE_MAP()
第二步:
在对话框类的.h文件添加消息函数声明。
// Generated message map functions
//{{AFX_MSG(CDis......

阅读全文(1255) | 评论:0

VC++下MIDI、WAV及CD的播放 (2007-04-24 09:32:00)

摘要:VC++下MIDI、WAV及CD的播放

武汉石化设计院电算室

周红汉

---- 加入音乐是增强应用程序功能的所有方法中最简单的一个。几乎每个计算机游

戏或多 媒体程序都以某种MIDI或CD音乐为背景。音乐可以使用户心情愉快;在合适

的场合播 放恰当的音乐能够使程序员和他的VC++程序焕发光彩。



第一部分 MIDI的播放

---- 乐器数字化接口(MIDI)是由音乐界的一些大公司(包括生产电子音乐合成器

的公司) 制订的一项协议,后来被计算机产业所采用并成为多媒体音乐文件的标准

格式。MIDI文件 一般较小,对硬件设备的要求高。



---- 一、 原理



---- 虽然MicroSoft支持MIDI文件,然而Visual C++或MFC并没有创建任何组件来实现

这种支持,但是MicroSoft API提供了三种不同的方法来实现MIDI的播放:



MCI(The Media Control Interface)。这是最基本的方法,本文将详细讨论这种方法。



流缓冲器。这种格式允许应用程序为MIDI数据分配缓冲器。在需要精确控制MIDI播放的

时候,流缓冲器将很有用处。



低级MIDI设备。需要完全控制MIDI数据的应用程序可以使用这种方法。

---- MCI可以通过mciSendCommand()和mciSendString()来完成,本文仅使用

mciSendCommand()函数。



---- 原型:DWORD mciSendCommand(UINT wDeviceID,UINT wMessage,DWORD dwParam1,DWORD dwParam2);



参数: wDeviceID:接受消息的设备ID

wMessage:MCI命令消息

dwParam1:命令的标志位

dwParam2:所使用参数块的......

阅读全文(3021) | 评论:0

Visual C++ MFC 中常用宏的含义(转载) (2007-04-22 15:11:00)

摘要:Visual C++ MFC 中常用宏的含义(转载)
    AND_CATCHAND_CATCH   AND_CATCH(exception_class,exception _object_point_name)   说明:   定义一个代码块,它用于获取废除当前TRY块中的附加异常类型。使用CATCH宏以获得一个异常类型 ,然后使用AND_CATCH宏获得随后的异常处理代码可以访问异常对象(若合适的话)已得到关于异常的特 别原因的更多消息。在AND_CATCH块中调用THROW_LAST宏以便把处理过程移到下个外部异常框架。 AND_CATCH可标记CATCH或AND_CATCH块的末尾。   注释:   AND_CATCH块被定义成为一个C++作用域(由花括号来描述)。若用户在此 作用域定义变量,那么记 住他们只在此作用域中可以访问。他也用于exception_object_pointer_name变量。   ASSERT   ASSERT(booleanExpression)   说明:   计算变量的值。如果结构的值为0,那么此宏便打印一个诊断消息并且成讯运行失败。如果条件为非 0,那么什么也不做。 诊断消息的形式为: assertion failed in file in line 其中name是元文件名 ,num是源文件中运行失败的中断号。在Release版中,ASSERT不计算表达式的值也就不中断程序。如果 必须计算此表达式的值且不管环境如何那么用VERIFY代替ASSERT。   注释:   ASSERT只能在Debug版中用   ASSERT_VAILD   ASSERT_VAILD(pObject)   说明:   用于检测关于对象的内部状态的有效性。ASSERT_VALID调用此对象的AssertValid成员函数(把它们 作为自己的变量来传递)。在 Release版中ASSERT_VALID什么也不做。在DEBUG版中,他检查指针,以不 同于NULL的方式进行检查,并调用对象自己的 AssertValid成员函数。如果这些检测中有任何一个失败 的话,那么他会以与ASSERT相同的方法显示一个警告的消息。   注释: ......

阅读全文(2261) | 评论:0

VC网络类编程:处理TCP网络传输“粘包”疑难(2007-04-16 13:03:00)

摘要: 在应用开发过程中,笔者发现基于TCP网络传输的应用程序有时会出现粘包现象(即发送方发送的若干包数据到接收方接收时粘成一包)。针对这种情况,我们进行了专题研究与实验。本文重点分析了TCP网络粘包问题,并结合实验结果提出了解决该问题的对策和方法,供有关工程技术人员参考。          一、TCP协议简介           TCP是一个面向连接的传输层协议,虽然TCP不属于iso制定的协议集,但由于其在商业界和工业界的成功应用,它已成为事实上的网络标准,广泛应用于各种网络主机间的通信。           作为一个面向连接的传输层协议,TCP的目标是为用户提供可靠的端到端连接,保证信息有序无误的传输。它除了提供基本的数据传输功能外,还为保证可靠性采用了数据编号、校验和计算、数据确认等一系列措施。它对传送的每个数据字节都进行编号,并请求接收方回传确认信息(ack)。发送方如果在规定的时间内没有收到数据确认,就重传该数据。数据编号使接收方能够处理数据的失序和重复问题。数据误码问题通过在每个传输的数据段中增加校验和予以解决,接收方在接收到数据后检查校验和,若校验和有误,则丢弃该有误码的数据段,并要求发送方重传。流量控制也是保证可靠性的一个重要措施,若无流控,可能会因接收缓冲区溢出而丢失大量数据,导致许多重传,造成网络拥塞恶性循环。TCP采用可变窗口进行流量控制,由接收方控制发送方发送的数据量。           TCP为用户提供了高可靠性的网络传输服务,但可靠性保障措施也影响了传输效率。因此,在实际工程应用中,只有关键数据的传输才采用TCP,而普通数据的传输一般采用高效率的udp。          二、粘包问题分析与对策         &nb......

阅读全文(2643) | 评论:0

PlaySound函数详解(2007-04-01 18:16:00)

摘要:PlaySound函数的声明为:

BOOL PlaySound(LPCSTR pszSound, HMODULE hmod,DWORD fdwSound);

使用这个函数时要加入“WINMM.lib”库,还要加入“MMSYSTEM.h”头文件。

参数pszSound是指定了要播放声音的字符串,该参数可以是WAVE文件的名字,或是WAV资源的名字,或是内存中声音数据的指针,或是在系统注册表WIN.INI中定义的系统事件声音。如果该参数为NULL则停止正在播放的声音。参数hmod是应用程序的实例句柄,当播放WAV资源时要用到该参数,否则它必须为NULL。参数fdwSound是标志的组合,如下表所示。若成功则函数返回TRUE,否则返回FALSE。

播放标志以及含义:

SND_APPLICATION
用应用程序指定的关联来播放声音。

SND_ALIAS
pszSound参数指定了注册表或WIN.INI中的系统事件的别名。

SND_ALIAS_ID
pszSound参数指定了预定义的声音标识符。

SND_ASYNC
用异步方式播放声音,PlaySound函数在开始播放后立即返回。

SND_FILENAME
pszSound参数指定了WAVE文件名。

SND_LOOP
重复播放声音,必须与SND_ASYNC标志一块使用。

SND_MEMORY
播放载入到内存中的声音,此时pszSound是指向声音数据的指针。

SND_NODEFAULT
不播放缺省声音,若无此标志,则PlaySound在没找到声音时会播放缺省声音。

SND_NOSTOP
PlaySound不打断原来的声音播出并立即返回FALSE。

SND_NOWAIT
如果驱动程序正忙则函数就不播放声音并立即返回。

SND_PURGE
停止所有与调用任务有关的声音。若参数pszSound为NULL,就停止所有的声音,否则,停止pszSound指定的声音。

SND_RESOURCE
p......

阅读全文(1780) | 评论:0

WSAAsyncSelect()函数详解(2007-03-28 23:55:00)

摘要:WSAAsyncSelect() 简述:
        通知套接口有请求事件发生.
       
        #include <winsock.h>

        int PASCAL FAR WSAAsyncSelect ( SOCKET s, HWND hWnd,
                        unsigned int wMsg,  long lEvent );
       
        s   标识一个需要事件通知的套接口的描述符.
        hWnd    标识一个在网络事件发生时需要接收消息的窗口句柄.
        wMsg    在网络事件发生时要接收的消息.
        lEvent  位屏蔽码,用于指明应用程序感兴趣的网络事件集合.
       
注释:
        本函数用来请求Windows Sockets DLL为窗口句柄发一条消息-无论它何时检测到由lEvent参数指明的网络事件.要发送的消息由wMsg参数标明.被通知的套接口由s标识.
        本函数自动将套接口设置为非阻塞模式.
        lEvent参数由下表中列出的值组成.
        值  &n......

阅读全文(3107) | 评论:0

Windows Sockets:操作顺序(2007-03-25 11:21:00)

摘要:本文以对照方式阐释了服务器套接字和客户端套接字的操作顺序。因为这些套接字使用 CArchive 对象,所以它们必然是流式套接字。流式套接字通信的操作顺序 在构造 CSocketFile 对象之前,下面的顺序对 CAsyncSocket 和 CSocket 都是准确的(只有少数几个参数不同)。从构造 CSocketFile 对象开始,顺序只适用于 CSocket 。下表阐释了在客户端和服务器之间设置通信的操作顺序。 设置服务器和客户端之间的通信 服务器 客户端 // construct a socket CSocket sockSrvr; // construct a socket CSocket sockClient; // create the SOCKET sockSrvr.Create(nPort); 1,2 // create the SOCKET sockClient.Create( ); 2 // start listening sockSrvr.Listen( ); // seek a connection sockClient.Connect(strAddr, nPort); 3,4 // construct a new, empty socket CSocket sockRecv; // accept connection sockSrvr.Accept( sockRecv ); 5 // construct file object CSocketFile file(&sockRecv); // construct file object CSocketFile file(&sockClient); // construct an archive CArchive arIn(&file,
CArchive::load); - 或 - CArchive arOut(&file,
CArchive::store); - 或两者 - // construct an archive CArchive arIn(&file, ......

阅读全文(1453) | 评论:0

 Socket CAsyncSocket CSocket CSocketFile(2007-03-24 18:55:00)

摘要:Socket有同步阻塞方式和异步非阻塞方式两种使用,事实上同步和异步在我们编程的生涯中可能遇到了很多,而Socket也没什么特别。虽然同步好用,不费劲,但不能满足一些应用场合,其效率也很低。
    也许初涉编程的人不能理解“同步(或阻塞)”和“异步(或非阻塞)”,其实简单两句话就能讲清楚,同步和异步往往都是针对一个函数来说的,“同步”就是函数直到其要执行的功能全部完成时才返回,而“异步”则是,函数仅仅做一些简单的工作,然后马上返回,而它所要实现的功能留给别的线程或者函数去完成。例如,SendMessage就是“同步”函数,它不但发送消息到消息队列,还需要等待消息被执行完才返回;相反PostMessage就是个异步函数,它只管发送一个消息,而不管这个消息是否被处理,就马上返回。

一、Socket API
    首先应该知道,有Socket1.1提供的原始API函数,和Socket2.0提供的一组扩展函数,两套函数。这两套函数有重复,但是2.0提供的函数功能更强大,函数数量也更多。这两套函数可以灵活混用,分别包含在头文件Winsock.h,Winsock2.h,分别需要引入库wsock32.lib、Ws2_32.lib。

1、默认用作同步阻塞方式,那就是当你从不调用WSAIoctl()和ioctlsocket()来改变Socket IO模式,也从不调用WSAAsyncSelect()和WSAEventSelect()来选择需要处理的Socket事件。正是由于函数accept(),WSAAccept(),connect(),WSAConnect(),send(),WSASend(),recv(),WSARecv()等函数被用作阻塞方式,所以可能你需要放在专门的线程里,这样以不影响主程序的运行和主窗口的刷新。
2、如果作为异步用,那么程序主要就是要处理事件。它有两种处理事件的办法:
    第一种,它常关联一个窗口,也就是异步Socket的事件将作为消息发往该窗口,这是由WinSock扩展规范里的一个函数WSAAsyncSelect()来实现和窗口关联。最终你只需要处理窗口消息,来......

阅读全文(4332) | 评论:0

用VC实现特定编辑框上对回车键响应(2007-03-17 14:53:00)

摘要: 文/青岛郎锐摘要:本文讲述了在指定的编辑框上能响应从键盘输入回车键的一种方法,对进程内消息的解析、动态获取指定资源ID等技术也作了简要描述。

  关键字:Microsoft Visual C++ 6.0、编辑框、回车键、消息、资源

  一、引言

  在通常的以CEditView为基类的单文档/多文档视图程序中,可以很好的响应键盘输入的回车键,只需比较最近两次的输入的字符,看看最新输入的字符是否内码是13(0x0d,回车键的内码)即可识别出来,而要单独把一个编辑框放入对话框中却根本不响应,这个看似简单的问题在实际应用中还是解决起来比较困难的。尤其是当一个充当表单录入的对话框上有若干个编辑框,这就要求在一个编辑框添完一项表单后用习惯的回车键将该编辑框上的数据读取到内存中去,并自动将光标移动到下一个编辑框中准备填写下一栏表单。无疑这种界面是十分人机友好的,使录入人员不必去执行每填一下表单就去按一下执行读入到缓存功能的按钮的烦琐操作。但上述功能的实现却并不象其演示的功能那样简单,下面本文就对这项技术的实现及附带的其他技术作简要的介绍。

  二、不能响应回车键的原因分析

  之所以在以CEditView作为基类的程序中可以响应回车键,是由于该程序的视类本身就是一个Edit控件,这就是问题的关键所在。CEditView作为CView的派生类能响应从键盘输入的各种消息,其中有和键盘输入相关的WM_CHAR、WM_KEYDOWN、WM_KEYUP等消息。我们就可以在这些消息的响应函数中灵活地设计程序去捕捉到回车键的输入,并执行响应的操作。

  当我们将编辑框作为一个普通的控件放到对话框上时情况就发生了变化。在此我们以CFormView为例,它也是CView的一个派生类,视是一个Form窗体(即对话框),当放有编辑框的窗体有回车键输入时,由于只有编辑框可以接受从键盘输入的字符,所以当键盘按下时统统把消息都发给了编辑框(在Windows下每个窗口、按钮、编辑框都看作一个窗口,都可以接受消息),可以通过ClassWizard在"Object IDs"选中编辑框所对应的ID号,在右边的消息框中可以看出该编辑框并不能响应WM_CHAR等消息,只能用EN_CHANGE事件来做类似的响应。可当我们加入了对该事......

阅读全文(1971) | 评论:0

基于TCP/IP的局域网多用户通信 转(2007-03-13 14:58:00)

摘要:基于TCP/IP的局域网多用户通信
作者:华东船舶工业学院机械系 袁 渊

摘要:基于TCP/IP的网络通信技术实现了面向连接的用户与服务器间点对点异步通信,本文在该基础上应用了多线程以及共享数据结构技术,使网络服务器具有了多用户间数据转发的功能,进而解决了局域网多用户间的通信问题。

关键词:TCP/IP;多线程;共享;通信;网络 引言 由于因特网的迅速流行,越来越多的应用程序具备了在网上与其它程序通信的能力。从WIN95开始微软把网络功能融进了它的操作系统,使得应用程序网络通信能力更为普及。因此,微软的TCP/IP协议也就成为网络应用程序基于的首选协议。 一般采用TCP/IP协议的应用程序只实现了单用户与服务器间点对点的连接,而本文在VC6.0的环境下,运用了了多线程以及共享数据结构技术,不仅实现了多用户与服务器间的连接,而且解决了多用户间信息互发问题----依靠服务器的转发功能。通过本文的阐述,希望能对那些需要编写多用户网络通信程序的读者以启发。 一、技术概述 1.1 基于TCP/IP的通信技术 基于TCP/IP的通信基本上都是利用SOCKET套接字进行数据通讯,程序一般分为服务器端和用户端两部分。下面简要地讲一下设计思路(VC6.0下): 第一部分 服务器端
  一、创建服务器套接字(create)。
  二、服务器套接字进行信息绑定(bind),并开始监听连接(listen)。
  三、接受来自用户端的连接请求(accept)。
  四、开始数据传输(send/receive)。
  五、关闭套接字(closesocket)。

第二部分 用户端
  一、创建用户套接字(create)。
  二、与远程服务器进行连接(connect),如被接受则创建接收进程。
  三、开始数据传输(send/receive)。
  四、关闭套接字(closesocket)。 通过以上设计思路,我们可以创建一个简单的面向连接的单用户程序。下面,将介绍多线程技术,以使程序支持多用户。 1.2 多线程技术 我们可以把线程看成是一个进程(执行程序)中的一个执行点,每个进程在任何给定时刻可能有若干个线程在运行。一个进程中的所有线程共享该进程中同样的地址空间,同样的......

阅读全文(1527) | 评论:0