|
We have a large application built using VC6 (SP6) which also involves MFC, running on WinXP SP3.
Now, when I tried to display the Print Property Sheet, available through the PrintDlgEx() function, and the LPPRINTDLGEX structure, I found that my CommDlg.h did not contain these definitions. For that purpose, I searched the 'Net and downloaded the last Platform SDK (February 2003 edition), which is supposed to work for VC6. I installed the SDK, updated the directory paths in the VC6 environment (keeping them at the top), but it still simply refuses to recognize these structures & functions, giving the C2065 (Undeclared identifier) conpiler errors.
Including Windows.h, commdlg.h has no effect. However, when the line #include "Windows.h" is placed above the #include "Stdafx.h" line, then the nature of errors changes, and we are redirected to the error line in afxwin32.h - MFC apps should not include Windows.h!!
Could anybody guide us here?
Thanks !
modified on Wednesday, May 5, 2010 6:33 AM
|
|
|
|
|
You probably need to define macros to tell the SDK that you want to use these features. Have a look at this page[^].
LPPRINTDLGEX was available in Windows 2000 and later, so you want to have these #defines BEFORE you #include any Windows SDK or MFC headers:
#define _WIN32_WINNT 0x0500
#define WINVER 0x0500
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
CodeProject MVP for 2010 - who'd'a thunk it!
|
|
|
|
|
If you will look at commdlg.h , you'll notice the #if preprocessor directives scattered throughout the file. They are looking at WINVER and _WIN32_WINNT .
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"Man who follows car will be exhausted." - Confucius
|
|
|
|
|
Thank you for your replies.
I'm sorry I failed to mention that I had tried defining these macros, both in the "App"View.cpp file, as well as in the stdafx.h file.
Now, upon your suggestion, I tried defining them in the "app"view.cpp file before including the stdafx file, as well as at the top of the stdafx.h file, but to no avail. It simply refuses to recognize this structure & function.
Interestingly, when I use the Page Setup dialog, it correctly displays the dialog, and when its definition is checked, it is the one located in the commdlg.h from the Platform SDK. So, this means that the path is ok, but it definitely has something to do with these macros. What about the STDMETHOD macro ? I don't understand this one, I'm afraid, and what it's supposed to do...
Would be very grateful for any further investigation into this issue!!
modified on Wednesday, April 28, 2010 2:15 AM
|
|
|
|
|
STDMETHOD is a COM definition, used to declare a method corrctly so it can be called through COM.
I would suggest you look at what comes out of the pre-processor (use the /P option for CL, the C++ compiler) to see what you're missing...
To make sure your SDK is OK, I would suggest putting the following in a C++ file (say a.cpp) and compiling it on the command-line with the command CL -I Path to your Platform SDK Include directory -C a.cpp .
#define WINVER 0x0500
#include <Windows.h>
#include <CommDlg.h>
LPPRINTDLGEX pPrintDlg;
If this doesn't compile correctly, there's something wrong with your SDK.
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
CodeProject MVP for 2010 - who'd'a thunk it!
|
|
|
|
|
When compiling the above cpp file, it gave the error message that it was unable to find "excpt.h" , which was included in Windows.h. Upon search, this file was found to be located in the following path within the PSDK: "..\Platform SDK\Include\Win64\CRT" . When this path was also added to the command line options, it complied fine.
When we look at the directory structure of the include files in this PSDK, it is rather different from that of VC98, especially w.r.t. to the MFC files. The MFC folder in the PSDK include directory doesn't contain any significant (no. of) files. These files are rather found under the Win64 directory.
What to do?
|
|
|
|
|
The PSDK does not contain MFC or ATL or standard include files. You need to have the compilers include directories in the include path *as well* as the PSDKs directories, but after the PSDKs directories in the INCLUDE/LIB search paths.
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
CodeProject MVP for 2010 - who'd'a thunk it!
|
|
|
|
|
They're all there....
As I said, everything else is working fine..It's even recognizing the Page Setup dialog function & structure in the same file (CommDlg.h) in the PSDK path), but just refuses to recognize the print property sheet function & structure....some (#if) conditions not being met ?
|
|
|
|
|
Pass your code through just the compiler's pre-processor (use the /P option). That will spit out a file containing the pre-processed text. you should be able to find which bits of commdlg.h are/are not being included in the program text, so can see (by comparison with the .h file) which #if is causing the bit of code you want to be omitted.
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
CodeProject MVP for 2010 - who'd'a thunk it!
|
|
|
|
|
Thanks a lot...we looked at the "*.i" file produced, and sure enough, the area of the code within the "#ifdef STDMETHOD" in the CommDlg.h file was not being included.
So after a couple of trials & errors, the inclusion of the following lines solved the problem:
#include <unknwn.h>
#include <basetyps.h>
after the line #include <afx_win.h> in the file stdafx.h.
|
|
|
|
|
Strange...I've never had to #include those explicitly...windows.h has always been enough...there's probably more to the story, but if you've managed to sort your immediate problem...
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
CodeProject MVP for 2010 - who'd'a thunk it!
|
|
|
|
|
Hi all
I've built a sample code named "enrollCustomCMC" in Windows SDK at "Microsoft SDKs\Windows\v6.1\Samples\Security\X509 Certificate Enrollment\VC" directory, but when the ".exe" file is built and I use it with the "Command Prompt", I see error in first "CoCreateInstance" function as "REGDB_E_CLASSNOTREG" that means: "Class not registered"!
I couldn't find the reason even with debugging!
The code is written using COM interface, here's the code:
#include <stdio.h>
#include <certenroll.h>
#include <certsrv.h>
#include <certcli.h>
#include <wincrypt.h>
#include "enrollCommon.h"
void Usage()
{
wprintf(L"Usage:\n");
wprintf(L"enrollCustomCMC <name> <value> <dns> <eku> \n");
wprintf(L"Example: enrollCustomCMC Name Value ");
wprintf(L"www.adatum.com 1.3.6.1.5.5.7.3.1\n");
}
HRESULT __cdecl wmain(__in int argc, __in_ecount(argc) wchar_t *argv[])
{
HRESULT hr = S_OK;
bool fCoInit = false;
ICertRequest2* pCertRequest2 = NULL;
ICertConfig* pCertConfig = NULL;
IX509Enrollment* pEnroll = NULL;
IX509CertificateRequest* pRequest = NULL;
IX509CertificateRequestPkcs10* pPkcs10 = NULL;
IX509CertificateRequestCmc* pCmc = NULL;
IX509Extensions* pExtensions = NULL;
IX509Extension* pExtension1 = NULL;
IX509Extension* pExtension2 = NULL;
IX509ExtensionEnhancedKeyUsage* pExtensionEKU = NULL;
IX509ExtensionAlternativeNames* pExtensionSAN = NULL;
IObjectId *pEKUObjectId = NULL;
IObjectId *pSANObjectId = NULL;
IObjectIds *pEKUObjectIds = NULL;
IObjectIds *pSANObjectIds = NULL;
IAlternativeName * anDnsName = NULL;
IAlternativeNames * pAlternativeNames = NULL;
IX509NameValuePair *pPair = NULL;
IX509NameValuePairs *pPairs = NULL;
PCWSTR pwszName;
PCWSTR pwszValue;
PCWSTR pwszDnsName;
PCWSTR pwszEKU;
BSTR strCAConfig = NULL;
BSTR strDnsName = NULL;
BSTR strName = NULL;
BSTR strValue = NULL;
BSTR strEKU = NULL;
BSTR strRequest = NULL;
BSTR strCert = NULL;
BSTR strDisposition = NULL;
LONG pDisposition = 0;
// Process command line arguments
if (argc != 5) {
Usage();
hr = E_INVALIDARG;
_JumpError(hr, error, "invalid arg");
}
else
{
pwszName = argv[1];
pwszValue = argv[2];
pwszDnsName = argv[3];
pwszEKU = argv[4];
}
// CoInitializeEx
hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
_JumpIfError(hr, error, "CoInitializeEx");
fCoInit = true;
// Create IX509CertificateRequestPkcs10
hr = CoCreateInstance(
__uuidof(CX509CertificateRequestPkcs10),
NULL, // pUnkOuter
CLSCTX_INPROC_SERVER,
__uuidof(IX509CertificateRequestPkcs10),
(void **) &pPkcs10);
_JumpIfError(hr, error, "CoCreateInstance");
// Initialize IX509CertificateRequestPkcs10
hr = pPkcs10->Initialize(ContextMachine);
_JumpIfError(hr, error, "Initialize");
// Create IX509CertificateRequestCmc
hr = CoCreateInstance(
__uuidof(CX509CertificateRequestCmc),
NULL, // pUnkOuter
CLSCTX_INPROC_SERVER,
__uuidof(IX509CertificateRequestCmc),
(void **) &pCmc);
_JumpIfError(hr, error, "CoCreateInstance");
// Initialize CMC request
hr = pCmc->InitializeFromInnerRequest(pPkcs10);
_JumpIfError(hr, error, "InitializeFromInnerRequest");
/* Create EKU extention from an OID */
// Create IObjectId
hr = CoCreateInstance(
__uuidof(CObjectId),
NULL,
CLSCTX_INPROC_SERVER,
__uuidof(IObjectId),
(void **) &pEKUObjectId);
_JumpIfError(hr, error, "CoCreateInstance");
// Allocate BSTR for EKU OID
strEKU = SysAllocString(pwszEKU);
if (NULL == strEKU)
{
hr = E_OUTOFMEMORY;
_JumpError(hr, error, "SysAllocString");
}
// Initialize IObjectId from EKU OID
hr = pEKUObjectId->InitializeFromValue(strEKU);
_JumpIfError(hr, error, "InitializeFromValue");
// Create IObjectIds
hr = CoCreateInstance(
__uuidof(CObjectIds),
NULL,
CLSCTX_INPROC_SERVER,
__uuidof(IObjectIds),
(void **) &pEKUObjectIds);
_JumpIfError(hr, error, "CoCreateInstance");
// Add IObjectId into IObjectIds collection
hr = pEKUObjectIds->Add(pEKUObjectId);
_JumpIfError(hr, error, "Add");
// Create IX509ExtensionEnhancedKeyUsage
hr = CoCreateInstance(
__uuidof(CX509ExtensionEnhancedKeyUsage),
NULL,
CLSCTX_INPROC_SERVER,
__uuidof(IX509ExtensionEnhancedKeyUsage),
(void **) &pExtensionEKU);
_JumpIfError(hr, error, "CoCreateInstance");
// Initialize IX509ExtensionEnhancedKeyUsage from IObjectIds
hr = pExtensionEKU->InitializeEncode(pEKUObjectIds);
_JumpIfError(hr, error, "InitializeEncode");
// QueryInterface of IX509Extension
hr = pExtensionEKU->QueryInterface(
__uuidof(IX509Extension),
(VOID **)&pExtension1);
_JumpIfError(hr, error, "QueryInterface");
/* Create SAN extention from a DNS Name */
// Create IAlternativeName
hr = CoCreateInstance(
__uuidof(CAlternativeName),
NULL,
CLSCTX_INPROC_SERVER,
__uuidof(IAlternativeName),
(void **) &anDnsName);
_JumpIfError(hr, error, "CoCreateInstance");
// Allocate BSTR for DNS name
strDnsName = SysAllocString(pwszDnsName);
if (NULL == strDnsName)
{
hr = E_OUTOFMEMORY;
_JumpError(hr, error, "SysAllocString");
}
// Initialize IAlternativeName
hr = anDnsName->InitializeFromString(
XCN_CERT_ALT_NAME_DNS_NAME,
strDnsName);
_JumpIfError(hr, error, "InitializeFromString");
// Create IAlternativeNames
hr = CoCreateInstance(
__uuidof(CAlternativeNames),
NULL,
CLSCTX_INPROC_SERVER,
__uuidof(IAlternativeNames),
(void **) &pAlternativeNames);
_JumpIfError(hr, error, "CoCreateInstance");
// Add IAlternativeName into IAlternativeNames collection
hr = pAlternativeNames->Add(anDnsName);
_JumpIfError(hr, error, "Add");
// Create IX509ExtensionAlternativeNames
hr = CoCreateInstance(
__uuidof(CX509ExtensionAlternativeNames),
NULL,
CLSCTX_INPROC_SERVER,
__uuidof(IX509ExtensionAlternativeNames),
(void **) &pExtensionSAN);
_JumpIfError(hr, error, "CoCreateInstance");
// Initialize IX509ExtensionAlternativeNames
hr = pExtensionSAN->InitializeEncode(pAlternativeNames);
_JumpIfError(hr, error, "InitializeEncode");
// QueryInterface of IX509Extension
hr = pExtensionSAN->QueryInterface(
__uuidof(IX509Extension),
(VOID **)&pExtension2);
_JumpIfError(hr, error, "QueryInterface");
/* Add EKU and SAN extension into CMC request */
// Get extensions from the CMC request
hr = pCmc->get_X509Extensions(&pExtensions);
_JumpIfError(hr, error, "get_X509Extensions");
// Add EKU extension into the request
hr = pExtensions->Add(pExtension1);
_JumpIfError(hr, error, "Add");
// Add SAN extension into the request
hr = pExtensions->Add(pExtension2);
_JumpIfError(hr, error, "Add");
/* Create name value pair and add it into CMC request */
// Create IX509NameValuePair
hr = CoCreateInstance(
__uuidof(CX509NameValuePair),
NULL, // pUnkOuter
CLSCTX_INPROC_SERVER,
__uuidof(IX509NameValuePair),
(void **) &pPair);
_JumpIfError(hr, error, "CoCreateInstance");
// Allocate BSTR for name
strName = SysAllocString(pwszName);
if (NULL == strName)
{
hr = E_OUTOFMEMORY;
_JumpError(hr, error, "SysAllocString");
}
// Allocate BSTR for value
strValue = SysAllocString(pwszValue);
if (NULL == strValue)
{
hr = E_OUTOFMEMORY;
_JumpError(hr, error, "SysAllocString");
}
// Initialize IX509NameValuePair
hr = pPair->Initialize(strName, strValue);
_JumpIfError(hr, error, "Initialize");
// Get IX509NameValuePairs from CMC request
hr = pCmc->get_NameValuePairs(&pPairs);
_JumpIfError(hr, error, "get_NameValuePairs");
// Add IX509NameValuePair into IX509NameValuePairs collection
hr = pPairs->Add(pPair);
_JumpIfError(hr, error, "Add");
/* Create enrollment request */
// Create IX509Enrollment
hr = CoCreateInstance(
__uuidof(CX509Enrollment),
NULL, // pUnkOuter
CLSCTX_INPROC_SERVER,
__uuidof(IX509Enrollment),
(void **) &pEnroll);
_JumpIfError(hr, error, "CoCreateInstance");
// Initialize IX509Enrollment from CMC request
hr = pEnroll->InitializeFromRequest(pCmc);
_JumpIfError(hr, error, "InitializeFromRequest");
// Create request
hr = pEnroll->CreateRequest(
XCN_CRYPT_STRING_BASE64,
&strRequest);
_JumpIfError(hr, error, "CreateRequest");
/* Submit request to SA CA, get response and install it */
// Create ICertConfig
hr = CoCreateInstance(
__uuidof(CCertConfig),
NULL,
CLSCTX_INPROC_SERVER,
__uuidof(ICertConfig),
(void**)&pCertConfig);
_JumpIfError(hr, error, "CoCreateInstance");
// Get the CA Config from UI
hr = pCertConfig->GetConfig(CC_UIPICKCONFIG, &strCAConfig);
_JumpIfError(hr, error, "GetConfig");
// Create ICertRequest2
hr = CoCreateInstance(
__uuidof(CCertRequest),
NULL,
CLSCTX_INPROC_SERVER,
__uuidof(ICertRequest2),
(void**)&pCertRequest2);
_JumpIfError(hr, error, "CoCreateInstance");
// Submit the request
hr = pCertRequest2->Submit(
CR_IN_BASE64 | CR_IN_FORMATANY,
strRequest,
NULL,
strCAConfig,
&pDisposition);
_JumpIfError(hr, error, "Submit");
// Check the submission status
if (pDisposition != CR_DISP_ISSUED) // Not enrolled
{
hr = pCertRequest2->GetDispositionMessage(&strDisposition);
_JumpIfError(hr, error, "GetDispositionMessage");
if (pDisposition == CR_DISP_UNDER_SUBMISSION) // Pending
{
wprintf(L"The submission is pending: %ws\n", strDisposition);
_JumpError(hr, error, "Submit");
}
else // Failed
{
wprintf(L"The submission failed: %ws\n", strDisposition);
pCertRequest2->GetLastStatus(&hr);
_JumpError(hr, error, "Submit");
}
}
// Get the certifcate
hr = pCertRequest2->GetCertificate(
CR_OUT_BASE64 | CR_OUT_CHAIN,
&strCert);
_JumpIfError(hr, error, "GetCertificate");
// Install the certifcate
hr = pEnroll->InstallResponse(
AllowNone,
strCert,
XCN_CRYPT_STRING_BASE64,
NULL);
_JumpIfError(hr, error, "InstallResponse");
error:
SysFreeString(strCAConfig);
SysFreeString(strDnsName);
SysFreeString(strName);
SysFreeString(strValue);
SysFreeString(strEKU);
SysFreeString(strRequest);
SysFreeString(strCert);
SysFreeString(strDisposition);
if (NULL != pCertRequest2) pCertRequest2->Release();
if (NULL != pCertConfig) pCertConfig->Release();
if (NULL != pEnroll) pEnroll->Release();
if (NULL != pRequest) pRequest->Release();
if (NULL != pPkcs10) pPkcs10->Release();
if (NULL != pCmc) pCmc->Release();
if (NULL != pExtensions) pExtensions->Release();
if (NULL != pExtension1) pExtension1->Release();
if (NULL != pExtension2) pExtension2->Release();
if (NULL != pExtensionEKU) pExtensionEKU->Release();
if (NULL != pExtensionSAN) pExtensionSAN->Release();
if (NULL != pEKUObjectId) pEKUObjectId->Release();
if (NULL != pSANObjectId) pSANObjectId->Release();
if (NULL != pEKUObjectIds) pEKUObjectIds->Release();
if (NULL != pSANObjectIds) pSANObjectIds->Release();
if (NULL != anDnsName) anDnsName->Release();
if (NULL != pAlternativeNames) pAlternativeNames->Release();
if (NULL != pPair) pPair->Release();
if (NULL != pPairs) pPairs->Release();
if (fCoInit) CoUninitialize();
return hr;
}
What's the problem?
And does this code need to a CA(certification Authority) to send request for?
Is it possible to run this code on XP client than Vista?
I asked this question on "Windows SDK" forum, but didn't get any respose!!
Please help me...
THX.
|
|
|
|
|
What are the setup instructions for the sample?
Are the COM classes registered using regsvr32.exe?
|
|
|
|
|
The documentation clearly states that these API's are available starting with Windows Vista. So no XP
|
|
|
|
|
I have no clue how to pass data to my threaded function.
_beginthread(MyThreadFunction, 0, NULL);
Tried to pass a value like in regular C++ functions.
_beginthread(MyThreadFunction(MyData), 0, NULL);
Kept getting compile errors!
|
|
|
|
|
Arguments to threads are usually passed as void pointers (void*).
So you need to pass in what ever is needed by typecasting it to a void*.
So if you want to pass an integer -
int i = 10;
_beginthread(MyThreadFunction, 0, (void*)&i);
|
|
|
|
|
How would the thread function declaration look like?
|
|
|
|
|
|
_beginthread(DownloadThread, 0, (void*) NewDownload);
void DownloadThread(void *D)
{
CDownload *Download = (CDownload*)D;
}
Compiles, but once the _beginthread is called the program crashes!
modified on Monday, April 26, 2010 3:39 PM
|
|
|
|
|
How is NewDownload declared?
|
|
|
|
|
1) Window that accepts URL
2) Pressing OK
3) Break down URL store it in CDownload *NewDownload;
4) After NewDownload has been filled out.
5) I pass NewDownload to download function to test if it the download function works
6) Add NewDownload to Linked List
Production code, user will be able to pause/resume called the download thread
|
|
|
|
|
Declaration, not implementation or use. In other words, is NewDownload a CDownload object?
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"Man who follows car will be exhausted." - Confucius
|
|
|
|
|
|
It seems passing Class Object part of a Linked List doesn't not work in this traditional manner!
|
|
|
|
|
Try something like this -
CDownload* NewDownload = new CDownload;
_beginthread(MyThreadFunction, 0, (void*)NewDownload);
|
|
|
|
|