| Home Forum RSS PGP Alerts Links (D) |
|
|
|
|
VC++ 6 items Comment on this article
Visual Studio
Linking MFC ATL Visual StudioClassView, Intelli(non)sense and #ifdef/#ifndefThere are several ways of making sure a header file isn't read more than once. The way I just chose screws up both intellisense and the classview pane; all classes simply disappear. There's a knowledgebase article (Q190965) that sheds some light on some very weird implementation issues with intellisense that seems to explain it. What it boils down to is that any #ifdef and #ifndef are checked in the header files, then the environment goes out to check if the macro in the #ifdef/#ifndef is in your project settings. If not, the #ifdef/#ifndef is regarded as true and everything from there to the matching #else or #endif is included both for intellisense and for the classview, but everything after the #else is ignored (the text from the article says a lot: "If the macro is undefined in the project, IntelliSense displays information for the first function, regardless of whether #ifdef or #ifndef is used.") Now get this straight: I'm not being sloppy is saying "the #ifdef/#ifndef is regarded as true"... that's exactly what happens and it's by design. Oh, my gawd... nobody even tried to interpret #ifndef as the opposite of #ifdef! But #else flips the meaning. What an interesting interpretation of logic this one is. So, in this example, the class disappears from classview and intellisense: // myClass.h
//
#ifdef MYCLASS_H
#pragma message("--* myClass.h already included")
#else
#define MYCLASS_H
... here's the core of the file
#endif
...but this works: // myClass.h
//
#ifndef MYCLASS_H
#define MYCLASS_H
... here's the core of the file
#else
#pragma message("--* myClass.h already included")
#endif
I'm usually impressed with mickeysoft. Right now I'm not. That I only discovered this little "feature" after fixing up 100+ header files according to the first pattern above, may have something to do with it. Linking problemsunresolved external _mainThis can happen when compiling for Unicode MinDependency. Solution: in settings for Unicode MinDependency, remove the commandline switch "/D ATL_MIN_CRT". MFCMFC support for ATL .EXE projectsTo add MFC support in ATL EXE projects, check out the following
knowledgebase articles: Q181505,
Q173974,
Q166480.
The following is the essential text from Q181505 and seems to work (note
my change; there's a pretty daft error in the original text and if not
changed, you'll get 'CoInitializeSecurity undefined' errors during
compile):
MFC class files added with ClassView or ClassWizard should now build without errors. User-defined messagesHandlers declared using: ON_MESSAGE(WM_USER_SOMETHING, OnSomething) get a prototype of: afx_msg LRESULT OnSomething(WPARAM, LPARAM); The returned LRESULT is returned to the called through SendMessage (and presumably lost through PostMessage), so by convention, return 0 if there's no particular reason to return something else. ATLInlineIsEqualGUID ambiguousIf you get loads of "InlineIsEqualGUID is ambiguous" errors, you've got a problem with the atlbase.h header file coming from the VC include libs, and the guiddefs.h file coming from the platform sdk. Then some namespace confusion, and you're on a roll. Fix: change the include <atlbase.h> in the stdafx.h to point to the platform sdk version, like: // #include <atlbase.h> drop this one, replace
with: See Q243298 for more details. Using SAFEARRAY's in IDLWhen you want to use SAFEARRAYs in IDL, and you add them using the "Add Method..." wizard, things go wrong. For example, adding a prototype like: SomeFunc([in] LONG lX, [in,out] SAFEARRAY(BSTR)* psaNames) ...results in the correct IDL syntax (same as above) but results in truncated function declarations and definitions in the class header and cpp files (or sometimes simply wrong prototypes like SAFEARRAY(BSTR)*... that simply don't work outside IDL files). You need to dress those up as follows (adding the red parts in this particular example): HRESULT SomeFunc(/*[in]*/ LONG lX, /*[in,out]*/ SAFEARRAY** ppsaNames); ActiveXCentura 1.5.xIf your ActiveX object doesn't have a "MiscStatus" set, and set right, in the registry, Centura goes really weird. No errors, but doesn't do anything with the control. To know what the flags in MiscStatus mean, check out the OLEMISC structure. For reasonable examples, check out this: .
.
ForceRemove 'Control'
ForceRemove 'Insertable'
ForceRemove 'ToolboxBitmap32' = s '%MODULE%, 104'
'MiscStatus' = s '0'
{
'1' = s '132497'
}
'TypeLib' = s '{00500881-B651-11D4-9DF6-006097BAB7CE}'
.
.
That magic number '132497' is suitable for a full control, invisible at runtime. For a runtime visible control, it can be '131473'. Instead of figuring out this by hand, create a new ATL object with the desired properties, then go read the wizard produced *.rgs file. STLtellgBad code: std::ifstream is;
char* buf[1024];
is.open("test");
while(!is.eof()) {
std::streampos pos = is.tellg();
is.getline(buf, 1024);
}
The "funny" thing is that if the file contains any linefeeds where there should be CR/FL pairs and it is opened in (default) text mode, the tellg() call screws up the next read position! Amazing, but true. One would have expected something called "tell..." to not change what it's telling you about, but not so. If you want to avoid obscure bugs, don't rely on the files always having correct CR/LF pairs, but open the stream in binary mode, like so: is.open("test", std::ios::binary);
Of course, you then have to strip the CR's and LF's from the returned strings yourself. This is how I do it: for (int i = strlen(m_buf) - 1; i >= 0; i--)
{
if (m_buf[i] != 0x0A && m_buf[i] != 0x0D) break;
m_buf[i] = '\0';
}
|
| TOP |