I am trying to figure out how to print in C++. I want to get the device context using the PrintDlgEx function, which needs a PRINTDLGEX structure. However, I cannot create a PRINTDLGEX because it says it's undeclared. I have included the Commdlg.h and Windows.h and linked the Comdlg32.lib, but all to no avail. Is there something I'm missing? I can go into the Commdlg header file and see that PRINTDLGEX is declared, but for some reason I can't use it? My operating system is Window Vista.
It's probably undeclared because it's within a #ifdef STDMETHOD block starting on line #878 of Commdlg.h
STDMETHOD is defined in basetyps.h
This post, Customizing PrintDlgEx and IPrintDialogCallback, might be useful as well.
You need to declare your target Windows version to be modern enough to support the structure, the defaults assume something ancient. Typically this will be done in your stdafx.h file. These definitions must come before the include of the Windows header files.
#define WINVER 0x0500
#define _WIN32_WINNT 0x0500
#define _WIN32_IE 0x0501
Related
I am experimenting with some Windows specific libraries in C++ (Using C libraries in my C++ code). I am trying to include objbase.h for CoCreateInstance() function:
#include <objbase.h>
// ...
HRESULT hr = CoCreateInstance(/* ... */);
My problem is with the VSCode C/C++ extension's intellisense. The code compiles ok, but the intellisense has some problems identifying this function. It has no problem with HRESULT, but for CoCreateInstance() it shows "identifier is undefined".
So I tried to look into the header file itself and figured out, the problem is, that the intellisense is recognizing some errors in the file and not letting me use the function, since it thinks it is not declared properly. It has no problem with the HRESULT, because it's just some simple typedef, that it understands. However the CoCreateInstance() is declared as:
WINOLEAPI CoCreateInstance( //...
where WINOLEAPI is a macro containing something like:
extern __declspec(dllimport) int __stdcall
I assume __declspec and __stdcall are some Windows specific keywords, and that the intellisense is simply not recognizing those, detecting an error, which makes the function undeclared, hence the "identifier is undefined" error.
Is this the cause of the problem? If so, is there any way to "teach" the intellisense something about those windows specific keywords? After all it is a Microsoft extension, I have no idea, why it wouldn't recognize Microsoft's C language extensions.
Update
I have found a temporary fix. See my answer below.
Update: Clarification
It seems that both combaseapi.h and objbase.h include all the dependencies they need, as even the intellisense is able to recognize __declspec (and __stdcall) as some "int __declspec" but it is unable to understand the syntax, where the type is surrounded by other keywords. It gives me an "explicit type is missing" error on the WINOLEAPI macro. When I replace the macro with its value explicitly as "extern __declspec(dllimport) int __stdcall", it gives me errors like "missing ;". So it seems, that it doesn't understand such syntax.
Add #include <windows.h> above objbaseapi.h
windows.h includes required definitions like for HRESULT ( Actually from winerror.h, but including windows.h should take care of it's dependents etc)
I found a temporary workaround. The WINOLEAPI macro is defined in the combaseapi.h file. I added these lines to the file after the WINOLEAPI definition:
// Original content of the file:
#ifdef _OLE32_
#define WINOLEAPI STDAPI
#define WINOLEAPI_(type) STDAPI_(type)
#else
#define WINOLEAPI EXTERN_C DECLSPEC_IMPORT HRESULT STDAPICALLTYPE
#define WINOLEAPI_(type) EXTERN_C DECLSPEC_IMPORT type STDAPICALLTYPE
#endif
// Added fix for VSCode intellisense:
#ifdef __INTELLISENSE__
#define WINOLEAPI EXTERN_C HRESULT
#define WINOLEAPI_(type) EXTERN_C type
#endif
Now when __INTELLISENSE__ is defined (It is not defined when compiling the code, but only when the intellisense examines the file.), it removes the unrecognized keywords from WINOLEAPI macro.
It would be nice though to apply some similar fix inside my code instead of modifying the included header. Also, this fixes only this particular situation, any of the other unsupported keywords must be treated separately. In my case, it fixes all problems in those two header files.
It works, but I would still appreciate if anyone provided some better solution.
Hi I currently have a problem redefining _WIN32_WINNT even though I have
#define _WIN32_WINNT 0x0600
#define WINVER _WIN32_WINNT
in my stdafx.h it still defaults to 0x0603
I'm currently using DDSTextureLoader that came with DirectX Tutorials and by beeing 603 it uses CreateFile2 and not CreateFile which creates an error :(
Remove all the #defines in the header files, and add the preprocessor definitions -D_WIN32_WINNT=0x0600;-DWINVER=_WIN32_WINNT in the project configuration. This makes sure that the definitions take effect at the very beginning of the compiling process. For the details, see here.
If it's not appropriate to remove the #defines in the headers. You may change them to the following:
#ifndef _WIN32_WINNT
# define _WIN32_WINNT 0x0600
#endif
#ifndef WINVER
# define WINVER _WIN32_WINN
#endif
All project created with MSVC have stdafx, which is precompiled headers, which I know what they are but what about targetver.h ? It includes SDKDDKVer.h, and I can't find what is that header about.
What is this for ?
targetver.h and SDKDDKVer.h are used to control what functions, constants, etc. are included into your code from the Windows headers, based on the OS that you want your program to support. I believe that targetver.h sets defaults to using the latest version of Windows unless the defines are specified elsewhere.
SDKDDKVer.h is the header file that actually defines the #defines that represent each version of Windows, IE, etc.
Line 193 of the SDKDDKVer.h (in SDK 8.1) states:
"if versions aren't already defined, default to most current"
This comment is specifically referring to the _WIN32_WINNT and NTDDI_VERSION macros.
So..
SDKDDKVer.h applies default values unless the macros have already been defined
the following code can be used to explicitly define the macros
#define _WIN32_WINNT 0x0601
#define NTDDI_VERSION 0x06010000
Interestingly enough, the SDKDDKVer.h header file has 'constant' values defined for all of the SDK versions. For example:
#define _WIN32_WINNT_WINXP 0x0501
#define _WIN32_WINNT_WIN7 0x0601
#define _WIN32_WINNT_WIN8 0x0602
One convention is to define _WIN32_WINNT and NTDDI_VERSIONin a header file called TargetVer.h, which you would reference in your pre-compiled header StdAfx.h.
#ADDTIONAL READING#
Update WINVER and _WIN32_WINNT
Using the Windows Headers
What does the Target Platform Version mean for a VS C++ project?
I have a bunch of Dll's in my project, using VStudio 9.0 compiler, pre-compiled headers are used for all my Dll's. The dll's loading process is done by implicit caller (.dll, .lib and header must be supplied).
I typically create a different macro definition file per dll, for instance if my current Dll is called MYMacroDll I add a file _MyMacroDll.h which contains:
#ifndef _MYMACRODLL_H_
#define _MYMACRODLL_H_
#ifdef _WIN32
#ifdef MYMACRODLL_EXPORTS
#define MYMACRODLL_API __declspec(dllexport)
#else
#define MYMACRODLL_API __declspec(dllimport)
#endif
#define MYMACRODLL_CALL __cdecl
#else
#define MYMACRODLL_API
#define MYMACRODLL_CALL
#endif
#endif
I know the code can be simplified but I keep the last defines for portability, at least, that's what I understood...
The pre-compiled header file pch.h, will always include the macro definition file _MyMacroDll.h, this makes things easier to me, 'cause later I can decide whether a new class or function will be interfaced or not. This so far works correct.
The confusion comes from using the dll interfaces in another dll; let's suppose a second dll ImageLoaderDll. This one uses instances or references of one (or several) of the interfaced classes/functions in _MyMacroDll. At first glance I guessed there was no need of including the _MyMacroDll.h, but when compiling the ImageLoaderDll it complains with
error C2470: '_AnInterfaceClassFromMyMacro' : looks like a function definition, but there is no parameter list; skipping apparent body
Then I have to include the _MyMacroDll.h in the pre-compiler header file of the other Dll, my project is becoming really messy and I find more and more useless dependencies.
What am doing wrong? Is there another way of setting up the macro definitions so I can avoid adding it to the client Dll's? Am not an expert regarding software design, but in this situation the more decoupled the better.
Hope my explanation was good enough.
If you are using the DLL interface from MyMacroDll in ImageLoaderDll, then you do have a dependency. ImageLoaderDll should include _MyMacroDll.h, otherwise you can't call its functions correctly. It's exactly the same as including <string.h> when you want to call strlen.
I am including a third party header and source file into my project.
At the top of the header there is this:
#if defined(WIN32) || defined(WIN16)
#ifndef MSDOS
#define MSDOS
#endif
#endif
#include <stdio.h>
#include <stdlib.h>
#ifndef MSDOS
#include <unistd.h>
#endif
#include "des.h"
The problem is that #if defined(WIN32) fails and the compilation fails when trying to #include unistd.h which I don't want to do.
I have third party project that works with this header file i.e. WIN32 is defined and it doesn't try to include In Visual Studio I did "Go To Definition" on "WIN32" and was taken to the following definition in WinDefs.h.
#define WIN32
I'm not sure this is where its getting WIN32 definition from, as the third party project does not appear to include "WinDefs.h".
So my problem is, how can I get WIN32 to be defined in my current new project?
Depends on your project setup. WIN32 is defined inside the windows header files, but you can pass it to the compiler as well ("-DWIN32" for gcc for example). Try it and see whether it compiles.
Visual Studio has the built-in define _WIN32. mingw-gcc has WIN32 and _WIN32 built-in so the project was likely tested using gcc. You might add
#if defined(_WIN32) && !defined(WIN32)
#define WIN32
#endif
or just add a -DWIN32 to the CFLAGS.
Check your includes. I am guessing that the third party header is included prior to the windows.h. So, in your main.cpp or equal it should be
#include <windows.h> // this will also include windefs.h
#include <thirdParty.h>
and not the other way around.
Hope that helps.
You can simply include the windows header files (windows.h) before including the third party header - as you already found out WIN32 is defined there but technicaly it could be defined anywhere (so if the third party project is not including the windows headers check if it's being defined in the compiler project settins directly).
BTW there is also a _WIN32 define that is set by the compiler, it's possibly a better idea to look for this define if checking if the code is being compiled under windows;
For those seeking answers to the
where is WIN32 defined
part of the questions, I've found it defined in:
minwindef.h
ole2.h
Note, I have no confidence that these are the only places it's defined. I expect there are probably other files where it's defined. Nevertheless, I thought this might help some people.
Some WIN32 defined in the compiler . Just like this,If you use the gcc for windows , WIN32 is defined . If you use the gcc for linux , WIN32 is not defined :)
So , the macros is a switch. You can define it to use somethine , and not define it to unuse something.