Pelles C forum
C language => Tips & tricks => Topic started by: DMac on April 04, 2006, 10:40:55 PM
-
I looked around for some way to easily echo version info in my application's about box. I found this function on Code Project and adapted it to work with Pelles (Originally MFC).
The CP article is referenced in the comments.
Enjoy
-
Hi DMac,
Realize this is old but time flies!
I downloaded this, I get a lot of errors if I try to compile with the new PellesC, by opening the project.
If I simply try to compile from scratch, I only get one error:
C:\Program Files\PellesC\Include\Win\winnt.h(558): fatal error #1014: #error: "No target architecture".
Any ideas?
I am trying to look at your work !
Tx, Ed
-
Use compiler option -Ze Enable Microsoft extensions ?
-
I downloaded and compiled this using 6.50.8 Release Candidate #4 32 bit.
I got an error for a typo "NUL" instead of "NULL". Fixed that and got one warning and a successful compile.
Are you using the 64 bit version?
Whatever the case if you go to Project>Project Options>Compiler Tab>in the dropdown labled "Machine:" Choose X86 and it should compile fine.
-
Ok,
I found the NUL, changed it to NULL
The compiler tab is already set to X86.
I am using the 32 bit version, I still get:
C:\Program Files\PellesC\Include\Win\winnt.h(558): fatal error #1014: #error: "No target architecture".
Timo if I now add the -Ze option, I get these errors:
Building main.obj.
D:\SGV1\C _RCDATA cmd into win32_exe Using TempFldr\Fr DMac GetVersionInfo\main.c(79): warning #2030: '=' used in a conditional expression.
D:\SGV1\C _RCDATA cmd into win32_exe Using TempFldr\Fr DMac GetVersionInfo\main.c(44): warning #2229: Local 'csRet' is potentially used without being initialized.
Building main.exe.
POLINK: error: Unresolved external symbol '__imp__VerQueryValueA@16'.
POLINK: fatal error: 1 unresolved external(s).
*** Error code: 1 ***
Done.
Tx for the speedy replies DMac and Timo, Ed (DMac I am using the identical release)
-
Do you have the calling convention set to stdcall on your compiler tab?
(Most windows calls us stdcall for x86, fastcall for x64)
-
Well it was stdcall.
I notice if I disable Microsoft extentions, I cannot set it to stdcall.
ten minutes later....
Ok, DMac was right. It compiles.
I went back to using DMac's project file, (which I should have done before after correcting "NULL", instead of building w a new project).
DMac does use _cdecl as the Calling conv, for the x86
but he checks *three* boxes:
Enable Microsoft extentions
Enable Pelles, and
Define compatibility names.
I did not have the second two checked.
Problem Solved.
Thanks you three !
Ed
-
Another version using example from // http://www.catch22.net/content/snippets (http://forum.pellesc.de// http://www.catch22.net/content/snippets)
From MicroSoft:
To retrieve the appropriate resource, before you call VerQueryValue, you must first call the GetFileVersionInfoSize function, and then the GetFileVersionInfo function.
look here too:
http://blogs.msdn.com/b/oldnewthing/archive/2006/12/26/1365215.aspx (http://blogs.msdn.com/b/oldnewthing/archive/2006/12/26/1365215.aspx)
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winver.h>
#include <stdio.h>
#pragma comment(lib, "version.lib")
#pragma comment(lib, "user32.lib")
LPSTR GetVersionInfo(TCHAR *szValue, TCHAR *szBuffer, ULONG nLength)
{
LPSTR csRet;
DWORD len;
TCHAR szFileName[MAX_PATH];
csRet = NULL;
if (GetModuleFileName(NULL, szFileName, sizeof(szFileName)))
{
len = GetFileVersionInfoSize(szFileName, 0);
csRet = NULL;
LPVOID ver = LocalAlloc(LPTR, len);
//LPVOID ver = GlobalAlloc(LPTR, len);
//ver = LocalLock(ver);
if (ver != NULL)
{
DWORD *codepage;
char fmt[256];
PVOID ptr = 0;
if (GetFileVersionInfo(szFileName, 0, len, ver))
{
if (VerQueryValue(ver, "\\VarFileInfo\\Translation", (LPVOID) & codepage, &len))
{
//wsprintf(fmt, "\\StringFileInfo\\%04x%04x\\%s", (*codepage) & 0xFFFF, (*codepage) >> 16, szValue);
wsprintf(fmt, "\\StringFileInfo\\%08x\\%s", (*codepage) << 16 | (*codepage) >> 16, szValue);
if (VerQueryValue(ver, fmt, &ptr, &len))
{
lstrcpyn(szBuffer, (TCHAR *)ptr, min(nLength, len));
csRet = szBuffer;
}
}
}
LocalFree(ver);
//GlobalFree(ver);
}
}
return csRet;
}
int __cdecl main(int argc, char *argv[])
{
char szTmp[260];
printf("%s\n",GetVersionInfo("Comments", szTmp, sizeof(szTmp)));
printf("%s\n",GetVersionInfo("CompanyName", szTmp, sizeof(szTmp)));
printf("%s\n",GetVersionInfo("FileDescription", szTmp, sizeof(szTmp)));
printf("%s\n",GetVersionInfo("InternalName", szTmp, sizeof(szTmp)));
printf("%s\n",GetVersionInfo("LegalCopyright", szTmp, sizeof(szTmp)));
printf("%s\n",GetVersionInfo("LegalTrademarks", szTmp, sizeof(szTmp)));
printf("%s\n",GetVersionInfo("OriginalFilename", szTmp, sizeof(szTmp)));
printf("%s\n",GetVersionInfo("PrivateBuild", szTmp, sizeof(szTmp)));
printf("%s\n",GetVersionInfo("ProductName", szTmp, sizeof(szTmp)));
printf("%s\n",GetVersionInfo("ProductVersion", szTmp, sizeof(szTmp)));
printf("%s\n",GetVersionInfo("SpecialBuild", szTmp, sizeof(szTmp)));
// And now for something we did not include in the version info
printf("\n%s\n",GetVersionInfo("FileName", szTmp, sizeof(szTmp)));
return 0;
}
If you still want do that with LoadResource without UNICODE, try this with allocated buffer:
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winver.h>
#include <stdio.h>
#pragma comment(lib, "version.lib")
#pragma comment(lib, "user32.lib")
LPSTR GetVersionInfo(TCHAR *szValue, TCHAR *szBuffer, ULONG nLength)
{
LPSTR csRet;
csRet = NULL;
HRSRC hVersion = FindResource(GetModuleHandle(NULL),
MAKEINTRESOURCE(VS_VERSION_INFO), RT_VERSION);
DWORD dwSize = SizeofResource(GetModuleHandle(NULL), hVersion);
if (hVersion != NULL)
{
HGLOBAL hGlobal = LoadResource(GetModuleHandle(NULL), hVersion);
if (hGlobal != NULL)
{
//LPVOID ver = LockResource(hGlobal);
LPVOID ver = LocalAlloc(LPTR, dwSize*2);
if (ver != NULL)
{
memcpy(ver, hGlobal, dwSize);
DWORD *codepage;
UINT len;
char fmt[0x40];
PVOID ptr = 0;
if (VerQueryValue(ver, "\\VarFileInfo\\Translation", (LPVOID) & codepage, &len))
{
//wsprintf(fmt, "\\StringFileInfo\\%04x%04x\\%s", (*codepage) & 0xFFFF, (*codepage) >> 16, csEntry);
wsprintf(fmt, "\\StringFileInfo\\%08x\\%s", (*codepage) << 16 | (*codepage) >> 16, szValue);
if (VerQueryValue(ver, fmt, &ptr, &len))
{
lstrcpyn(szBuffer, (TCHAR*)ptr, min(nLength, len));
csRet = szBuffer;
}
}
LocalFree(ver);
}
FreeResource(hGlobal);
}
}
return csRet;
}
int main(int argc, char *argv[])
{
char szTmp[260];
printf("%s\n",GetVersionInfo("Comments", szTmp, sizeof(szTmp)));
printf("%s\n",GetVersionInfo("CompanyName", szTmp, sizeof(szTmp)));
printf("%s\n",GetVersionInfo("FileDescription", szTmp, sizeof(szTmp)));
printf("%s\n",GetVersionInfo("InternalName", szTmp, sizeof(szTmp)));
printf("%s\n",GetVersionInfo("LegalCopyright", szTmp, sizeof(szTmp)));
printf("%s\n",GetVersionInfo("LegalTrademarks", szTmp, sizeof(szTmp)));
printf("%s\n",GetVersionInfo("OriginalFilename", szTmp, sizeof(szTmp)));
printf("%s\n",GetVersionInfo("PrivateBuild", szTmp, sizeof(szTmp)));
printf("%s\n",GetVersionInfo("ProductName", szTmp, sizeof(szTmp)));
printf("%s\n",GetVersionInfo("ProductVersion", szTmp, sizeof(szTmp)));
printf("%s\n",GetVersionInfo("SpecialBuild", szTmp, sizeof(szTmp)));
// And now for something we did not include in the version info
printf("\n%s\n",GetVersionInfo("FileName", szTmp, sizeof(szTmp)));
return 0;
}
-
Tx Timo,
Will be studying this over.
Appreciate much.
..Ed