·天新网首页·加入收藏·设为首页
首页|笔记本|手机|数码相机|摄像机|MP3/MP4|主板|内存|显示器|办公|打印机|下载|开发|汽车|学院|业界
硬件|台式机|数码|数字家庭|投影仪|GPS/CPU|显卡|硬盘|服务器|网络|一体机|驱动|源码|游戏|考试|报价
您现在的位置:天新网 > 软件开发 > 开发语言 > C++ Builder
用C++Builder实现Windows 2000的Messenger
http://dev.21tx.com 2003年01月20日 天极网 刘纪锋


  本文讲述了如何用C++Builder实现Messenger的详细方法,其中使用了如下技术:

  1. 多线程序技术,防止界面出现死锁。

  2. 使用了网络枚举来枚举在线的网络用户。

  3. 使用了Unicode的转换函数进从AnsiString到Unicode的转换。

  4. 使用了简单的不规则窗口的技术。

  5. 自动安装,将自己加入系统起动中。

  6. 系统托盘技术。

  编程方法:

  1. 如图所示在窗体上加入的有的控件:TListView,TTreeView,TMemo,菜单、托盘、按钮、状态栏

  

  2. 针对各控件按本文所写加入代码即可。

  3. 以下是发送函数

void __fastcall TFormMain::ButtonSendClick(TObject *Sender)
{
 AnsiString Message,UserName,FromName;
 TListItem *ListItem;
 if(CheckBoxAnony->Checked)FromName=EditAnony->Text;
 else FromName="";
 Message=Memo1->Text;
 if(Message==""){ShowMessage("Please Enter words to send");return;}
 if(!ListView1->SelCount){
  if(TreeView1->Selected==NULL){ShowMessage("Please select destnation");return;}
  UserName=TreeView1->Selected->Text;
  if(TreeView1->Selected->Level==1)UserName=UserName+"*";
  new NetMessageSend(false,UserName,FromName,Message,CheckBoxGetRet->Checked);
 return;
 }
 ListItem=ListView1->Selected;
 UserName=ListItem->Caption;
 if(TreeView1->Selected->Level==0)UserName+="*";
 while(UserName[1]=='\\')UserName=UserName.SubString(2,UserName.Length()-1);
 new NetMessageSend(false,UserName,FromName,Message,CheckBoxGetRet->Checked);
 for(int i=1;iSelCount;i++){
 ListItem=ListView1->GetNextItem(ListItem,sdAll,TItemStates()<  UserName=ListItem->Caption;
 if(TreeView1->Selected->Level==0)UserName+="*";
 while(UserName[1]=='\\')UserName=UserName.SubString(2,UserName.Length()-1);
 new NetMessageSend(false,UserName,FromName,Message,CheckBoxGetRet->Checked);
 }
}

  以下是网络结点枚举函数,是个线程

bool __fastcall EnumNetResource::GetNetRes(TTreeNodes *Nodes,TTreeNode * Node,NETRESOURCE *pNetResource,int Depth)
{
#define ENUMBUFSIZE (16*1024)
#define ENUMCOUNT 10
NETRESOURCE buff[1024];
AnsiString UserName;
if(Terminated) return false;
if(Nodes==NULL) return false;
if(Depth==0) return true;
HANDLE hEnum;
bool reValue=true;
NETRESOURCE *pNetRes,NetRes;
if(WNetOpenEnum(RESOURCE_GLOBALNET,RESOURCETYPE_ANY,0,
pNetResource,&hEnum)!=NO_ERROR)return false;
DWORD ECount=ENUMCOUNT;
DWORD ESize=ENUMBUFSIZE;
DWORD Error_num;
do{
Error_num=WNetEnumResource(hEnum,&ECount,buff,&ESize);
if (ESize>ENUMBUFSIZE) return false;
if (Error_num==NO_ERROR){
for (DWORD num=0;num if(Terminated)return false;
pNetRes=&buff[num];
file://if(Node)Node->ImageIndex=1-Depth;
UserName=AnsiString(pNetRes->lpRemoteName);
while(UserName[1]=='\\')UserName=UserName.SubString(2,UserName.Length()-1);
TTreeNode *tNode=Nodes->AddChild(Node,UserName);
if(tNode)
switch(pNetRes->dwType){
case RESOURCETYPE_ANY:
switch(tNode->Level){
case 0:tNode->ImageIndex=1;break;
case 1:
case 2:tNode->ImageIndex=2;break;
}
break;
case RESOURCETYPE_DISK:tNode->ImageIndex=3;break;
case RESOURCETYPE_PRINT:tNode->ImageIndex=4;break;
}
if(pNetRes->dwDisplayType!=RESOURCEDISPLAYTYPE_SHARE){
if(!GetNetRes(Nodes,tNode,pNetRes,Depth-1)) reValue=false;
}
}
}
}while(ECount==ENUMCOUNT);
if (Error_num!=ERROR_NO_MORE_ITEMS && Error_num!=NO_ERROR) reValue=false;
WNetCloseEnum(hEnum);
return reValue;
}

  以下是多线程发送函数,是个线程

void __fastcall NetMessageSend::Execute()
{
file://---- Place thread code here ----
const maxlen=1600;
wchar_t *pMsgBuff;
AnsiString retstr;
long int retvalue,msglen,sendlen;
msglen=FMessage.WideCharBufSize();
pMsgBuff=(wchar_t *)malloc(msglen*2+10);
FMessage.WideChar(pMsgBuff,msglen);
for(long int i=0;i if((msglen*2-i)>maxlen)sendlen=maxlen;
else sendlen=msglen*2-i;
retvalue=NetMessageBufferSend(NULL,FUserName,pFromName,(char *)pMsgBuff+i,sendlen);
}
if(FGetRet){
switch(retvalue){
case NERR_Success:
retstr="@_@ Sent OK!";
break;
case ERROR_Access_DENIED:
retstr=":( Has no access";
break;
case ERROR_INVALID_PARAMETER:
retstr=":( Parameter error.";
break;
case ERROR_NOT_SUPPORTED:
retstr=":( Network not supported.";
break;
case NERR_NameNotFound:
retstr=":( Parameter is invalid.";
break;
case NERR_NetworkError:
retstr=":( General failure network hardware.";
break;
default:
retstr=":( Unknow error";
break;
}
Application->MessageBox(retstr.c_str(),("Result for "+AnsiString(FUserName)).c_str(),MB_OK);
}
free(pMsgBuff);
}

  本文代码在C++ Builder6.0,Windows2000专业版下实现。

上一篇: 在 C++ Builder中利用串行通信控件编程
下一篇: C++Builder中集合的处理

Google
 
热点文章
关于我们 | 联系我们 | 广告服务 | 工作机会 | 版权声明 | 欢迎投稿 | 网站地图
Copyright © 2000-2008 , www.21tx.com , All Rights Reserved .
© 晨新科技 版权所有 Created by TXSite.net