|
Actually is not as easy as it looks.
Unless you really need to retrieve localized version info size, use GetFileVersionInfoSize instead GetFileVersionInfoSizeEx. GetFileVersionInfoSize is available starting with Windows 2000. You do not have to call LoadLibrary and GetProcAddress since your module (exe) is linked implicitly with Version.lib.
To write robust code you would have to write more than simple GetProcAddress.
If you really want to use both, depending on the operating system, you will have to retrieve proc address depending on OS version and load appropriate procedure address, since Version.lib contains both: ASCII and UNICODE versions of the functions.
If your app is built as ANSII you would have to use ANSI version of the function: GetFileVersionInfoSizeExW or GetFileVersionInfoSizeW depending on what system your app is running on.
For unicode build you will have to explicitly request UNICODE versions: GetFileVersionInfoSizeExW or GetFileVersionInfoSizeA.
Something like this:
void GetFileVersionLenInfo()
{
OSVERSIONINFO osvi = {sizeof(OSVERSIONINFO)};
DWORD dwHandle = 8000;
DWORD dwVer = 0;
GetVersionEx(&osvi);
HINSTANCE hInst = NULL;
#ifdef _USE_EXPLICIT
typedef DWORD (CALLBACK* lpfnGETFILEVERSIONINFOSIZEEX)(DWORD, LPCTSTR, LPDWORD);
typedef DWORD (CALLBACK* lpfnGETFILEVERSIONINFOSIZE)(LPCTSTR, LPDWORD);
hInst = LoadLibrary(_T("VERSION.dll"));
if(osvi.dwMajorVersion > 5)
{
#ifdef UNICODE
lpfnGETFILEVERSIONINFOSIZEEX lpfnGetFileVersionInfoSizeEx = (lpfnGETFILEVERSIONINFOSIZEEX)GetProcAddress(hInst, "GetFileVersionInfoSizeExW");
#else
lpfnGETFILEVERSIONINFOSIZEEX lpfnGetFileVersionInfoSizeEx = (lpfnGETFILEVERSIONINFOSIZEEX)GetProcAddress(hInst, "GetFileVersionInfoSizeExA");
#endif // UNICODE
dwVer = lpfnGetFileVersionInfoSizeEx(FILE_VER_GET_NEUTRAL,
_T("C:\\Program Files\\Beyond Compare 2\\BC2.exe"),
&dwHandle);
return;
}
#ifdef UNICODE
lpfnGETFILEVERSIONINFOSIZE lpfnGetFileVersionInfoSize = (lpfnGETFILEVERSIONINFOSIZE)GetProcAddress(hInst, "GetFileVersionInfoSizeW");
#else
lpfnGETFILEVERSIONINFOSIZE lpfnGetFileVersionInfoSize = (lpfnGETFILEVERSIONINFOSIZE)GetProcAddress(hInst, "GetFileVersionInfoSizeA");
#endif // UNICODE
dwVer = lpfnGetFileVersionInfoSize(
_T("C:\\Program Files\\Beyond Compare 2\\BC2.exe"),
&dwHandle);
#else
dwVer = GetFileVersionInfoSize(
_T("C:\\Program Files\\Beyond Compare 2\\BC22.exe"),
&dwHandle);
DWORD dwError = GetLastError();
#endif
}
Uncomment _USE_EXPLICITTo compile using explicit link that checks for the OS version and loads appropriate versions of functions depending on UNICODE being defined or not.
JohnCz
|
|
|
|
|
I changed to the non ex version for now, turns out I have a lot of errors to fix in my program to run in XP nice and smooth. I haven't written all the code for the GetFileVersionInfo yet, I have to package the program first, post it on the internet, and then go back and finish the code. Give me a couple of days to experiment with your post, so I can comment on it.
But thanks for the extra help.
|
|
|
|
|
Another thing to check:
Is your project using targetver.h? If yes, change constants to define 0x0500 to target Windows XP.
If not, make sure you define WINVER, _WIN32_WINNT and _WIN32_WINDOWS as 0x500 in stdafx.h before any include.
Compiler will then flag all errors coming from usage of the functions that are not defined in XP.
JohnCz
|
|
|
|
|
Yes, the wizard included it in my stdafx.h, and rc file. So I should do a temp 0x500 to make all the XP errors surface?
I think it was just the 4 functions, when I moved the project to vista to make sure that it worked, and worked all the UAC stuff. Then I moved it back to XP just to make sure all was good, and to build my deployment project.
stdafx.h
#pragma once
#include "targetver.h"
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
// Windows Header Files:
#include <windows.h>
// C RunTime Header Files
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <tchar.h>
// TODO: reference additional headers your program requires here
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")
|
|
|
|
|
That is not guaranteed. It may also depend on SDK version you are using for build.
Compiler will flag errors if header files contain #ifdef with specific versions of windows around some functions to exclude definition for certain versions of Windows.
So, you may have some help in finding out what is excluded for XP but you may still be left with some unknowns to resolve on your own.
JohnCz
|
|
|
|
|
That's good advice. Let me try it on a temp basis first, and see the results. I can learn from it at least, and implement it correctly later on down the road.
|
|
|
|
|
Hello Friends
I am using tabcontrol first time in MFC.So,I have some question for this.
1.)I am creating a dilog in which at a time I have to show four tabs but maximum number of tabs are more than 200. As I saw that one tabCtrl showing only five tabs.
How can i Achieve this?
2.)On one tab ,i have to show seven buttons whose color will change on tab.So,fo that Do i need to create a dilaog with seven button and then add it into tab? But how Do i this for all tabs?
Thanks In Advance.
Regards
Yogesh
|
|
|
|
|
200 Tabs??
You should look into this google [^]and get an insight of what Tab control is and how to create tab controls. The links give you lots of links to other websites.
It is worth looking into some of them
Every new day is another chance to change your life.
|
|
|
|
|
Thanks For Reply.
i read all stuff related to Tab.
I came across to a problem.I am creating a tab on which I want to insert a dialog which is having seven buttons.
But when I use
m_ctlTab.inserItem for Dilaog in OnInitDialog(), it is crashing.
Do we need to set anything else to initialize tab?
Regards
Yogesh
|
|
|
|
|
yogeshs wrote: But when I use
m_ctlTab.inserItem for Dilaog in OnInitDialog(), it is crashing.
You need to use your debugger to find out exactly what is happening to cause the crash.
Binding 100,000 items to a list box can be just silly regardless of what pattern you are following. Jeremy Likness
|
|
|
|
|
Are you sure is crashing or just asserting? Most likely it is the latter and it looks something like this:
ASSERT(IsWindow(hwnd));
With limited info you gave in your post, I can only guess that tab object was not created (windows is not attached to the MFC object). You have to either call Create or subclass the tab control.
I would strongly suggest two things:
Reconsider 200 tabs; it seems a little too many to handle by the user (not to mention control).
Consider using property sheet (CPropertySheet) and property pages (CPropertyPage). Property pages behave like dialogs.
JohnCz
|
|
|
|
|
The msdn says #pragma pack(n) will change current alignment value to n.
But if n is zero, what will do?
|
|
|
|
|
it resets the packing to the default size
(actually, what it does depends on the compiler. some compilers don't support pack(0) at all, and some use it as a reset)
modified 22-Apr-12 14:33pm.
|
|
|
|
|
Nope. Default size is NOT stating a #pragma pack, which defaults to DWORD, ie 4 byte alignment in structures.
#pragma pack 0 means there is no packing between data members, so they are contiguous in memory.
--edit--
Actually I am talking crap. pack (1) makes data member contiguous in memory, pack (0) resets packing. DOh!
==============================
Nothing to say.
modified 23-Apr-12 4:37am.
|
|
|
|
|
Erudite_Eric wrote: pragma pack 0 means there is no packing between data members, so they are contiguous in memory.
no. that's pack(1) : align on single bytes.
pack(n) specifies the structure alignment, not the number of bytes between structs.
|
|
|
|
|
Doh! Quite correct.
==============================
Nothing to say.
|
|
|
|
|
Here n has to be 1,2 4, 8 ....
Now if don't specify any value or if the value is 0, then the members are packed to default packing size (which is 8 for many compilers).
However few compilers will throw compilation error.
|
|
|
|
|
Nope. Default size is NOT stating a #pragma pack, which defaults to DWORD, ie 4 byte alignment in structures.
#pragma pack 0 means there is no packing between data members, so they are contiguous in memory.
--edit--
Actually I am talking crap. pack (1) makes data member contiguous in memory, pack (0) resets packing. DOh!
(Just checked my code. Its been a few months since I did any, I guess the old memory is fading....)
==============================
Nothing to say.
modified 23-Apr-12 4:38am.
|
|
|
|
|
#pragma pack(0)
#include <iostream>
using namespace std;
struct Test
{
char a;
int i;
};
void main()
{
cout<<sizeof(Test)<<endl;
}
I am using VS2008 SP1. The build is x86.
Now guess the result of sizeof(Test) ??
|
|
|
|
|
5
==============================
Nothing to say.
|
|
|
|
|
I am reading 8 on my console.
|
|
|
|
|
Yeah, it is 8, DWORD alignment. I got it wrong...
==============================
Nothing to say.
|
|
|
|
|
|
#pragme pack 0 takes out all pading between data members in a struct so they are contiguous in memory. Very useful indeed since pretty much every data stream has no padding since it wastes bandwidth so being able to cast a chunk of memory to some zero packed struct gives you immediate and easy access to those data members.
Consider an ethernet framed IP packet containing UDP and DHCP data. You can build a struct to grab the IP address requested directly from the data.
--edit--
Actually I am talking crap. pack (1) makes data member contiguous in memory, pack (0) resets packing. DOh!
==============================
Nothing to say.
modified 23-Apr-12 4:39am.
|
|
|
|
|
Why don't you continue reading MSDN ?
#pragma pack documentation[^] states:
Valid values are 1, 2, 4, 8, and 16.
Hence 0 is 'not valid' (I wouldn't try to make assumptions on a value marked as such).
Veni, vidi, vici.
|
|
|
|