杂记

来源:互联网 发布:指纹算法性能测试方法 编辑:程序博客网 时间:2024/04/28 06:58

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;
}