请帮忙看下,有没有更简单的写法。

tianweisoft_com 2011-02-22 02:48:45
[code=C]/C++
hwnd1 = FindWindow(NULL, "A");
hwnd2 = FindWindow(NULL, "B");
hwnd3 = FindWindow(NULL, "C");
hwnd4 = FindWindow(NULL, "D");
hwnd5 = FindWindow(NULL, "E");

// 这里的问题,我有很多个需要检查的字符。有二十多个,如果按现在的方法,就要一直到hwnd24,这样的写法会不会影响执行的效率呢,有没有更简单一些的方法。
if (hwnd1 != NULL || hwnd2 != NULL || hwnd3 != NULL || hwnd4 != NULL || hwnd5 != NULL)
{

PrepareExit();
MessageBox(NULL,
"异常错误:\r\n"
"出现错误!",
"错误信息",
MB_OK|MB_ICONSTOP);
goto Label_End;
}
}

Label_End:
return 0;

[/code]
...全文
68 点赞 收藏 7
写回复
7 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
fishion 2011-02-22
HWND hwnd[20];
CString str = "A";
char ch = 'A';
int i;
for(i=0;i<20;++i,str.Format("%c",'A'+i);)
FindWindow(NULL,str);
for(i=0;i<20&&hwnd[i];i++);
if(i!=20)
MessageBox(NULL,
"异常错误:\r\n "
"出现错误! ",
"错误信息 ",
MB_OK|MB_ICONSTOP);
break;
回复
qiuxin425 2011-02-22
用数组循环
回复
onlyliu 2011-02-22

BOOL GetRstFindWND(CString strInfo)//返回真就不为空
{
BOOL bRst=FALSE;
HWND hwnd;
hwnd = FindWindow(NULL, strInfo);
if(hwnd!=NULL)
bRst=TRUE;
else
bRst=FALSE;
return bRst;
}
//////////////////////////////

for(int i=0;i<20;i++)
{
if(!GetRstFindWND(CString strInfo))
{
PrepareExit();
MessageBox(NULL,
"异常错误:\r\n "
"出现错误! ",
"错误信息 ",
MB_OK|MB_ICONSTOP);
break;
}

}

回复
xuwei__5720 2011-02-22
可以写两个数组:CString str[24];HWND hWnd[24];
str[0]=L"A";str[1]=L"B";str[2]=L"C";.....
for(int i=0;i<24;i++)
{hWnd[i]=FindWindow(NULL,str[i]);}
for(int i=0;i<24;)
{if(hwnd[i]==NULL)
i++;
else break;
}
if(i != 23)
{
PrepareExit();
MessageBox(NULL,
"异常错误:\r\n "
"出现错误! ",
"错误信息 ",
MB_OK|MB_ICONSTOP);
goto Label_End;
}

这样看起来稍微好点了吧,也没有乱了
回复
webipstin 2011-02-22
用楼上的办法

表驱动
  一,什么是表驱动
  表驱动,又称之为表驱动法、表驱动方法。
  “表”是几乎所有数据结构课本都要讨论的非常有用的数据结构。表驱动方法出于特定的目的来使用表,程序员们经常谈到“表驱动”方法,但是课本中却从未提到过什么是"表驱动"方法。表驱动方法是一种使你可以在表中查找信息,而不必用很多的逻辑语句(if或Case)来把它们找出来的方法。事实上,任何信息都可以通过表来挑选。在简单的情况下,逻辑语句往往更简单而且更直接。但随着逻辑链的复杂,表就变得越来越富有吸引力了,通过下面的这个例子大家就能知道什么是所谓的表驱动方法了。
  假设你需要一个可以返回每个月中天数的函数(为简单起见不考虑闰年),
  一个比较笨的方法是一个大的if语句:
[code=C]/C++  int iGetMonthDays(int iMonth)
  {
  int iDays;
  if(1 == iMonth) {iDays = 31;}
  else if(2 == iMonth) {iDays = 28;}
  else if(3 == iMonth) {iDays = 31;}
  else if(4 == iMonth) {iDays = 30;}
  else if(5 == iMonth) {iDays = 31;}
  else if(6 == iMonth) {iDays = 30;}
  else if(7 == iMonth) {iDays = 31;}
  else if(8 == iMonth) {iDays = 31;}
  else if(9 == iMonth) {iDays = 30;}
  else if(10 == iMonth) {iDays = 31;}
  else if(11 == iMonth) {iDays = 30;}
  else if(12 == iMonth) {iDays = 31;}
  return iDays;
  }[/code]
  可以看出本来应该很简单的一件事情,代码却是这么冗余,解决这个的办法就可以用表驱动方法。
[code=C]/C++  static int aiMonthDays[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
  // 我们可以先定义一个静态数组,这个数组用来保存一年十二个月的天数
  int iGetMonthDays(int iMonth)
  {
  return aiMonthDays[(iMonth - 1)];
  }[/code]
  接下来不用多说了,大家都能看出用这种表驱动的方法代替这种情逻辑性不强,但分支很多的代码是多么令人"赏心悦目"的了。
  函数:
  函数指针在表驱动方法中的应用
  在使用表驱动方法时需要说明的一个问题是,你将在表中存储些什么。
  在某些情况下,表查寻的结果是数据。如果是这种情况,你可以把数据存储在表中。
  在其它情况下,表查寻的结果是动作。在这种情况下,你可以把描述这一动作的代码存储在表中。
  在某些语言中,也可以把实现这一动作的子程序的调用存储在表中,也就是将函数的指针保存在表中,当查找到这项时,让程序用这个函数指针来调用相应的程序代码,这个就是函数指针在表驱动方法中的应用。
  其实说到这已经说了很多表驱动方法的相关问题了,现在要把函数指针也应用进去,很多人应该已经想到会是个什么样子了,其实也很简单,通过下面这两段伪代码的例子就可以充分体现函数指针在表驱动方法中应用会使代码更加精致。
  我们在写一段程序的过程中会经常遇到这样的问题,我们在写一个Task的主函数中有时会要等待不同的Event通知,并且处理不同的分支,首先有如下的Event Bit的宏定义和相应的处理函数的声明。
[code=C]/C++  #define TASK_EVENT_BIT00 (1 << 0)
  #define TASK_EVENT_BIT01 (1 << 1)
  #define TASK_EVENT_BIT02 (1 << 2)
  #define TASK_EVENT_BIT03 (1 << 3)
  #define TASK_EVENT_BIT04 (1 << 4)
  #define TASK_EVENT_BIT05 (1 << 5)
  #define TASK_EVENT_BIT06 (1 << 6)
  #define TASK_EVENT_BIT07 (1 << 7)
  #define TASK_EVENT_BIT08 (1 << 8)
  #define TASK_EVENT_BIT09 (1 << 9)
  void vDoWithEvent00();
  void vDoWithEvent01();
  void vDoWithEvent02();
  void vDoWithEvent03();
  void vDoWithEvent04();
  void vDoWithEvent05();
  void vDoWithEvent06();
  void vDoWithEvent07();
  void vDoWithEvent08();
  void vDoWithEvent09();[/code]
  我们一般首先想到的写法是
[code=C]/C++  unsigned long ulEventBit;
  for(;;)
  {
  xos_waitFlag(&ulEventBit);
  if(ulEventBit & TASK_EVENT_BIT00)
  {
  vDoWithEvent00();
  }
  if(ulEventBit & TASK_EVENT_BIT01)
  {
  vDoWithEvent01();
  }
  if(ulEventBit & TASK_EVENT_BIT02)
  {
  vDoWithEvent02();
  }
  if(ulEventBit & TASK_EVENT_BIT03)
  {
  vDoWithEvent03();
  }
  if(ulEventBit & TASK_EVENT_BIT04)
  {
  vDoWithEvent04();
  }
  if(ulEventBit & TASK_EVENT_BIT05)
  {
  vDoWithEvent05();
  }
  if(ulEventBit & TASK_EVENT_BIT06)
  {
  vDoWithEvent06();
  }
  if(ulEventBit & TASK_EVENT_BIT07)
  {
  vDoWithEvent07();
  }
  if(ulEventBit & TASK_EVENT_BIT08)
  {
  vDoWithEvent08();
  }
  if(ulEventBit & TASK_EVENT_BIT09)
  {
  vDoWithEvent09();
  }
  }[/code]
  可以看出这样写是不是显得程序太长了呢。
  下面我们再看看同样的一段代码用函数指针和表驱动方法结合的方法写出会是什么样子。
[code=C]/C++  typedef struct {
  unsigned long ulEventBit;
  void (*Func)(void);
  } EventDoWithTable_t;
  /* 定义EventBit 与相应处理函数关系的结构体 */
  static const EventDoWithTable_t astDoWithTable[] = {
  { TASK_EVENT_BIT00 , vDoWithEvent00},
  { TASK_EVENT_BIT01 , vDoWithEvent01},
  { TASK_EVENT_BIT02 , vDoWithEvent02},
  { TASK_EVENT_BIT03 , vDoWithEvent03},
  { TASK_EVENT_BIT04 , vDoWithEvent04},
  { TASK_EVENT_BIT05 , vDoWithEvent05},
  { TASK_EVENT_BIT06 , vDoWithEvent06},
  { TASK_EVENT_BIT07 , vDoWithEvent07},
  { TASK_EVENT_BIT08 , vDoWithEvent08},
  { TASK_EVENT_BIT09 , vDoWithEvent09}
  };
  /* 建立EventBit与相应处理函数的关系表 */
  ulong ulEventBit;
  int i;
  for(;;)
  {
  xos_waitFlag(&ulEventBit);
  for(i = 0 ; i < sizeof(astDoWithTable)/sizeof(astDoWithTable[0]); i ++)
  {
  if ( ( ulEventBit & astDoWithTable[i].ulEventBit ) &&
  ( astDoWithTable[i].Func != NULL ) )
  {
  (*astDoWithTable[i].Func)();
  /* 通过函数指针来调用相应的处理函数 */
  }
  }
  }[/code]
  可以看出这种代码的风格使代码变得精致得多了,并且使程序的灵活性大大加强了,如果我们还要再加入EventBit,只修改表中的内容就可以了。
  总结
  通过上面介绍的,相信大家已经对函数指针的使用方法有所了解了,但是需要提醒大家,凡事都要具体情况具体分析,使用函数指针的时候一定要多加小心,因为函数指针有它的一个致命的缺点。
  函数指针的致命缺点是:无法对参数 (parameter) 和返回值 (return value) 的类型进行检查,因为函数已经退化成指针,指针是不带有这些类型信息的。少了类型检查,当参数或者反回值不一致时,会造成严重的错误。有些编译器并不会帮我们找出函数指针这样的致命错误。所以,许多新的编程语言都不支持函数指针了,而改用其他方式。
  从上面的例3中我们可以看到
[code=C]/C++  int max(int x,int y){ return x>y?x:y; }
  int min(int x,int y){ return x<y?x:y; }
  int add(int x,int y){ return x+y; }[/code]
  这三个函数都有两个参数,而在后面却把处理函数定义成
[code=C]/C++  int process(int x,int y, int (*f)())
  {
  return (*f)(x,y);
  }[/code]
  其中第三个参数是一个函数的指针,从表面上看它是个没有参数,并且返回int型的函数的指针,但是在后面却用process(a,b,max)的方式进行调用,max带有两个参数,这段程序在C语言中就可以顺利的编译通过(但是在C++中却编译不通过),可以看出如果编译器没有检查出错误,而我们又不小心写错的话,后果是很严重的,比如return (*f)(x,y);不小心写成return (*f)(x);在C语言中可以正常的被编译通过,但是运行结果一定不是我们想要的。
  因此在C语言中使用函数指针的时候,一定要小心“类型陷阱”,小心地使用函数指针,只有这样我们才可以从函数指针中获益。
回复
huziwu 2011-02-22
你只是判断条件为不空就出提示信息的话,有个笨方法:
DWORD dwhWnd = hwnd1+hwnd12+hwnd3+...+hwnd24;
或用数组表示hwnd1~24就更方便了:
DWORD dwhWnd = 0;
for(int i=0;i<24;i++)
dwhWnd +=hwnd[i];
if(dwhWnd!=0)
{
PrepareExit();
MessageBox(NULL,
"异常错误:\r\n "
"出现错误! ",
"错误信息 ",
MB_OK|MB_ICONSTOP);
goto Label_End;
}
回复
sxqinge 2011-02-22
将FindWindow()函数给封装起来吧
HWND GetWindow(char* str)
{
HWND hwnd;
hwnd = FindWindow(NULL, str);
return hwnd;
}
回复
相关推荐
发帖
VC/MFC
创建于2007-09-28

1.5w+

社区成员

VC/MFC相关问题讨论
申请成为版主
帖子事件
创建了帖子
2011-02-22 02:48
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……