![]() ![]() |
|
用C++Builder实现Windows2000的Messenger | |
作者:佚名 文章来源:不详 点击数 更新时间:2008/4/18 14:38:38 文章录入:杜斌 责任编辑:杜斌 | |
|
|
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专业版下实现。 |
|
![]() ![]() |