He,YuanHui —— 业精于勤荒于嬉,行成于思毁于随

如果你喜欢一个事,又有这样的才干,那就把整个人都投入进去,就要象一把刀直扎下去直到刀柄一样,不要问为什么,也不要管会碰到什么。

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  240 随笔 :: 1 文章 :: 135 评论 :: 2 引用

公告

 

=================================================
本文为HeYuanHui原作

转载必须确保本文完整并完整保留原作者信息及本文原始链接!

NN:      khler
E-mail: khler@163.com
QQ:     23381103
MSN:   pragmac@hotmail.com
=================================================


    用VC++写的MFC程序,不管是exe的或者dll,都有个'VERSION'资源,在里面可以指定程序的版本号,这样在程序文件上右键点击,查看属性,就可以看到内嵌的版本信息了。同样,所有程序都愿意在'About'对话框中显示程序的当前版本,但是这里如何显示,跟资源里的'VERSION'信息还是有好几毛钱的关系呢 :)

    如果我们从'VERSION'资源里获取版本信息并在about对话框中显示,那么我们每次发布的时候只要修改'VERSION'里的信息就行了,经过一定处理,就可以在about对话框中显示了。

    其实MSDN中也有说明,但是说实话,要想从'VERSION'中读取信息,还真不是件简单的事情,下面一一实现,代码大部分来自MSDN。

    结果如下图所示:

显示1.1.6 build 718

 

    代码:

 

void CAboutDlg::OnShowWindow(BOOL bShow, UINT nStatus)
{
 CDialog::OnShowWindow(bShow, nStatus);

 
// TODO: 在此处添加消息处理程序代码


 CString ver 
= GetAppVersion(L"TowerWatch.exe");
 
if(ver.IsEmpty()) return;

 
int pos = ver.ReverseFind('.');
 CString mainVer 
= ver.Left(pos);
 CString build 
= ver.Right(ver.GetLength() - pos -1);
 GetDlgItem(IDC_STATIC_VER)
->SetWindowText(mainVer);
 GetDlgItem(IDC_STATIC_BUILD)
->SetWindowText(build);

}

void ErrorExit(LPTSTR lpszFunction) 

 
// Retrieve the system error message for the last-error code

 LPVOID lpMsgBuf;
 LPVOID lpDisplayBuf;
 DWORD dw 
= GetLastError(); 

 FormatMessage(
  FORMAT_MESSAGE_ALLOCATE_BUFFER 
| 
  FORMAT_MESSAGE_FROM_SYSTEM 
|
  FORMAT_MESSAGE_IGNORE_INSERTS,
  NULL,
  dw,
  MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  (LPTSTR) 
&lpMsgBuf,
  
0, NULL );

 
// Display the error message and exit the process

 lpDisplayBuf 
= (LPVOID)LocalAlloc(LMEM_ZEROINIT, 
  (lstrlen((LPCTSTR)lpMsgBuf)
+lstrlen((LPCTSTR)lpszFunction)+40)*sizeof(TCHAR)); 
 StringCchPrintf((LPTSTR)lpDisplayBuf, 
  LocalSize(lpDisplayBuf),
  TEXT(
"%s failed with error %d: %s"), 
  lpszFunction, dw, lpMsgBuf); 
 MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT(
"Error"), MB_OK); 

 LocalFree(lpMsgBuf);
 LocalFree(lpDisplayBuf);
}

 

CString CAboutDlg::GetAppVersion(WCHAR
* AppName) 
{
 CString   AppVersion; 

 DWORD   RessourceVersionInfoSize; 
 DWORD   JustAJunkVariabel; 
 WCHAR
*   VersionInfoPtr; 
 
struct   LANGANDCODEPAGE
 { 
  WORD   wLanguage; 
  WORD   wCodePage; 
 }   
*TranslationPtr; 
 WCHAR
*     InformationPtr; 
 UINT      VersionInfoSize; 
 WCHAR     VersionValue[
255]; 

 RessourceVersionInfoSize
=GetFileVersionInfoSize(AppName,&JustAJunkVariabel); 
 
if(0!=RessourceVersionInfoSize) 
 {
  VersionInfoPtr 
= new WCHAR[RessourceVersionInfoSize];
  
if(!GetFileVersionInfo(AppName,0,RessourceVersionInfoSize,VersionInfoPtr)) 
  {
    ErrorExit((LPTSTR)L
"GetFileVersionInfo");
   delete[]   VersionInfoPtr; 
   
return NULL; 
  } 

  
if(!VerQueryValue( VersionInfoPtr, L"VarFileInfo\\Translation", (LPVOID*)&TranslationPtr, &VersionInfoSize)) 
  { 
   ErrorExit((LPTSTR)L
"VerQueryValue");
   delete[]   VersionInfoPtr; 
   
return NULL; 
  } 

  
// retrieve product version
  wsprintf(VersionValue, L"\\StringFileInfo\\%04x%04x\\ProductVersion", TranslationPtr[0].wLanguage, TranslationPtr[0].wCodePage); 

  
if(!VerQueryValue( VersionInfoPtr, VersionValue, (LPVOID*)&InformationPtr, &VersionInfoSize)) 
  { 
   ErrorExit((LPTSTR)L
"VerQueryValue");
   delete[]   VersionInfoPtr; 
   
return NULL; 
  } 
  
if(wcslen(InformationPtr)> 0)   //Not   Null 
  { 
   AppVersion
=CString(InformationPtr); 
  } 

  delete[]   VersionInfoPtr; 
 } 
 
return   AppVersion; 

 

当然,你可以将分解Version和build部分代码也封装到GetAppVersion函数中。

 

 

posted on 2011-02-25 13:44 He,YuanHui 阅读(...) 评论(...) 编辑 收藏

Add to Google