2008-05-22
DLL 自己的消息循环(win32 DLL):
在DLL中,通过CreateWindow创建窗口。就利用该窗口的消息循环作为DLL的消息循环。通过map把消息ID和消息响应函数关联起来,这个工作在程序初始化的时候完成(还没有进行消息循环)。关联需要处理的消息(包括系统消息和自定义消息)后, 再创建窗口。 该窗口的处理函数中,通过消息ID在map中查找该消息的处理函数,如果没有找到就用 DefWindowProc 来处理。(看来也可以用MFC来做)。
自己的消息映射:
在较大项目中,下层向窗口发送消息需要知道目标窗口的句柄,很多当窗口很多时代码很乱很难维护,需要自己的消息映射机制。目的是:下层只管发送消息即可,自己的消息循环机制通过map把 IDMsg 映射到窗口句柄,进而可以成功发送消息,即下层不需要知道目标窗口的句柄只要知道要发送的消息ID即可。
简单的模拟代码:
#ifndef _MESSAGEPUBLISHER_H //文件 MessagePublisher.h
#define _MESSAGEPUBLISHER_H
#include <iostream>
#include <map>
#include <list>
class IMessagePublisher
{
public:
virtual void AttachMessage(UINT aiMsgID , HWND hwnd)=0;
virtual void OnMessage( UINT message, WPARAM wParam, LPARAM lParam )=0;
};
class CMessagePublisher : IMessagePublisher
{
public :
/*使窗口可以订阅消息, 把消息和窗口句柄添加到map中*/
virtual void AttachMessage(UINT aiMsgID , HWND hwnd);
/*发送消息*/
virtual void OnMessage( UINT message, WPARAM wParam, LPARAM lParam );
private :
/*消息的Map映射,以MsgID为Key, Value 为Wnd的List*/
std::map<UINT , std::list<HWND > > mmMsgWndMap;
};
#endif
#include "stdafx.h"
#include "MessagePublisher.h" //文件 MessagePublisher.cpp
/*使窗口可以订阅消息, 把消息和窗口句柄添加到map中*/
void CMessagePublisher::AttachMessage(UINT aiMsgID , HWND hwnd)
{
std::map<UINT , std::list<HWND > >::iterator lmapiter = NULL ;
lmapiter=mmMsgWndMap.find(aiMsgID);
if(lmapiter==mmMsgWndMap.end())
{
std::list<HWND > llstwnd;
std::pair< std::map<UINT, std::list<HWND > >::iterator, bool > pr ;
/*加入列表的头节点*/
pr = mmMsgWndMap.insert(std::pair<UINT, std::list<HWND > >(aiMsgID, llstwnd));
//mmMsgWndMap[aiMsgID]=llstwnd;
if (pr.second==true)
{
/*加入List*/
lmapiter = pr.first;
lmapiter->second.push_back(hwnd);
}
}else
{
lmapiter->second.push_back(hwnd);
}
}
/*发送消息*/
void CMessagePublisher::OnMessage( UINT message, WPARAM wParam, LPARAM lParam )
{
using namespace std ;
map<UINT , std::list<HWND > >::iterator lmapiter=NULL;
/*查找该消息对应的订阅者List*/
lmapiter=mmMsgWndMap.find(message);
if( lmapiter!=mmMsgWndMap.end() )
{
/*向所有订阅者发送该消息*/
std::list<HWND > &llst = lmapiter->second ;
std::list<HWND >::iterator llstiter = NULL ;
for (llstiter=llst.begin(); llstiter!=llst.end(); llstiter++)
{
PostMessage(*llstiter, message, wParam, lParam);
}
}
}
取得本机所有IP地址: getaddrinfo
int main(void)
{
int rc;
char name[20]; //得到的主机名
char ipbuf[16]; // 保存ip地址
struct addrinfo hints,*addr;
memset(&hints,0,sizeof(struct addrinfo));
hints.ai_family=AF_INET;
hints.ai_flags=AI_CANONNAME;
hints.ai_flags=AI_ADDRCONFIG;
gets(name); //从输入得要查找的主机名
if((rc=getaddrinfo(name,NULL,&hints,&addr))==0)
{
//inet_ntop(int af, const void *src,char *dst, size_t cnt)函数中src是指向struct in_addr类型的
//而不是struct sockaddr,所以应改成
do
{
printf("ip: %s,host: %s/n",inet_ntop(AF_INET,&((struct sockaddr_in *)addr->ai_addr)->sin_addr,ipbuf,sizeof(ipbuf)),addr->ai_canonname);
}while((addr=addr->ai_next)!=NULL); //打印找到的主机地址和主机名
return 0;
}
printf("%d/n",rc);//检查出错时的rc值
return 0;
}