用C++Builder實現(xiàn)Windows2000的Messenger

字號:

文講述了如何用C++Builder實現(xiàn)Messenger的詳細方法,其中使用了如下技術:
    1. 多線程序技術,防止界面出現(xiàn)死鎖。
    2. 使用了網(wǎng)絡枚舉來枚舉在線的網(wǎng)絡用戶。
    3. 使用了Unicode的轉(zhuǎn)換函數(shù)進從AnsiString到Unicode的轉(zhuǎn)換。
    4. 使用了簡單的不規(guī)則窗口的技術。
    5. 自動安裝,將自己加入系統(tǒng)起動中。
    6. 系統(tǒng)托盤技術。
    編程方法:
    1. 在窗體上加入的有的控件:TListView,TTreeView,TMemo,菜單、托盤、按鈕、狀態(tài)欄
    2. 針對各控件按本文所寫加入代碼即可。
    3. 以下是發(fā)送函數(shù)
     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);
    }
    }
    以下是網(wǎng)絡結(jié)點枚舉函數(shù),是個線程
    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;
    }