|
Respected All contributors,
I am developing a program to be run in all windows platform. Its running in tablet and desktop pc. The code was portable to WM5.0 and its running in the release mode. When i build it in DEBUG mode the file size is very big (28MB). The emulator says "System running crtially low in resources", which can be understood. The debug version of the file in Windows Desktop is about 15MB. It has many graphics files embeeded and i have reduced the size of those files including a 246BYTE graphics file for all resources.
I opened the DEBUG file in BINARY format in VS to see wether it has any reference to any BIG BINARY FILES. I have seen that it has allmost 9MB of text which directly or indirectly pointing to "AFXTEMPL.H"
For Example::
H:\Program Files\Microsoft Visual Studio 8\VC\ce\atlmfc\include\afxtempl.h
Or
f:\sp\vctools\vc7libsce\ship\atlmfc\include\afxtempl.h
While the directory does not exist in my system. The text is approximately 9MB. I dont know what has caused the compiler to include so much text to the DEBUG binary and its causing the DEBUG file to be big in size and unable to load in EMULATOR.
I did check with mcafee virus scan for any virus, it said no viruses detected. I created an MFC smart Device Application in SDI format and run it without adding any code to the default AppWizard generated files. It also shows similar problem and included a BIG size of text similar to the above shown text in the DEBUG build. All the MFC related projects shows the same problem, wether its dll , activex or standalone.
This is a cad project and does not have any linking to ODBC or DB or any other similar items. It uses the GDI and no external libraries, but since the AppWizard generated files itself showing the problem. There might be something else wrong!!!
Recreate the problem:
Start MS VC 2005 Sp1. File -> New -> Project -> Smart Device -> MFC Smart Device Application
Platforms -> Windows Mobile 6.0 Profesional SDK
Finish. & Run
Open the file in the VS Editor (MS VC 6.0 eVC4.0 or 3.0) in binary mode. Search for text "afxtempl.h" in the created executable file in debug mode. Thanks in advance for your effort. The file that was created on my machine for the form view SDI is (1,631,232 bytes). Is that normal?
I request all the contrinutors to give some light into this if you had faced similar problems or heard of it!!!
I have added a youtube video showing the problem::
http://www.youtube.com/watch?v=nA2d3gCtglk
All Comments and thoughts welcome...
Thank you very much for your time,
Have a nice Day.
Sincerely
Suresh Kumar
|
|
|
|
|
Whenever you build a debug build, the compiler records the source file and line number of every statement that's compiled in in the debug information. When you use a C++ template, you get a separate copy of the code for each different set of parameters for the template. Sometimes the compiler can consolidate them but it may not do this for debug builds.
I would normally expect the debug information to be recorded in the Program Database (.pdb) file. However, some options cause it to be recorded in the actual executable and I suspect you've set one of those.
Also note that the default in Visual Studio 2005 is to use MFC in a static library. This means that the prebuild .lib files are statically linked into your executable. The debug options to the linker turn off the /opt:ref option, which causes unused code to be discarded, which means that the entirety of the runtime is linked into your program. This could be another source of lots of the overhead.
I don't currently have the tools installed but will confirm once I have (just upgrading to Windows Vista now).
DoEvents: Generating unexpected recursion since 1991
|
|
|
|
|
Thank you very much for your time.
I have set the /opt ref option, but it does not solve the problem. If you could get the time, please do create a smart device MFC enabled project (preferably MFC->SDI->Form View) and check the generated debug binary to see the amount of text dumped into it. my desktop debug does not dump this much amount and has added only a single reference to "Afxtempl.h", which is ideal and consumes only below MAX_PATH byte in the debug binary.
If i am unclear on any thing, please do let me know.
Thanking you.
Suresh
|
|
|
|
|
I can confirm that the newly-generated project for a Windows Mobile 6 Professional MFC SDI app is indeed around 1.6MB.
I've also worked out what the source of the information is. It's down to use of ASSERT .
The definition of ASSERT is as follows (afx.h, line 416):
#define ASSERT(f)\
DEBUG_ONLY((void) ((f) ||\
!::AfxAssertFailedLine(THIS_FILE, __LINE__) ||\
(AfxDebugBreak(), 0))) (reformatted for clarity).
The THIS_FILE macro is defined as __FILE__ . This is a built-in macro that expands to the filename of the current file being processed. Recording the file and line number in this way allows a meaningful message box to be displayed if the assertion fails. Most MFC headers don't contain any significant implementation, so don't perform any ASSERTs, but afxtempl.h has its implementation in the class body (it has to, they're templates) and does.
The reason that there are two paths is that the ones coming from uses of afxtempl.h in the static MFC library were included in that library when it was built - this is the path that doesn't exist on your computer. The other is the one coming from uses of the header in your code. You may think you don't use it, but in fact for some reason the MFC classes CPtrArray and CMapPtrToPtr have been defined in terms of CArray<> and CMap<> , respectively. These classes are used by CArchive which is at the root of the document-saving facility. I have no idea why this is the case - maybe someone thought they were saving space by omitting these non-template classes! Worse, they're still included in afxcoll.h, and in the MFC libraries, anyway!
I think all you can try is to use the 'string pooling' option (/GF) in the compiler options (Configuration Properties, C/C++, Code Generation, Enable String Pooling). This causes identical constant string literals to only be included in each compiled source file once, but note that they're stored in read-only memory so you might need to check that you don't try to write back to string literals.
I forgot to mention that /opt:ref removes unreferenced COMDATs. A COMDAT is basically just a marked independent chunk of code. For a debug build, the compiler effectively emits a single COMDAT per source file except where C++ semantics require that there's only a single definition of something (for example, the out-of-line version of an inline function). If you specify the /Gy option (Code Generation, Enable Function-Level Linking), the compiler emits each function as its own COMDAT. This can be annoying for debugging, however, as you can only call referenced code from the debugger expression evaluator. If there's a function that wasn't referenced in your program, the linker will eliminate it. The /DEBUG option to the linker suppresses the default /OPT:REF - if you want both you have to explicitly enable /OPT:REF.
DoEvents: Generating unexpected recursion since 1991
|
|
|
|
|
I got accustomed to programming in Borland C++ 4.5, which does not use classes. Please where can I download some Visual C++ programs (it does not matter what they do), so I can see how to program for Windows using classes (e.g. the class called "Window")?
|
|
|
|
|
Its easy to use of classes (your classes or MFC classes)
class CMyclass: public CImage
{
public:
CMyclass(CWnd* pParent = NULL);
};
.....
....
void CMain::functions()
{
CMyclass localclass;
CDC m_Images; //MFC class
}
|
|
|
|
|
Anthony Appleyard wrote: I got accustomed to programming in Borland C++ 4.5, which does not use classes.
Did you use a C++ compiler to compile only plain C code?
Anthony Appleyard wrote: Please where can I download some Visual C++ programs (it does not matter what they do), so I can see how to program for Windows using classes (e.g. the class called "Window")?
If you have the Visual Studio 2008 Express Edition (as you stated it in a previous post) then you cannot use the MFC classes (e.g. CWnd ).
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
|
|
|
|
|
My Borland C++ 4.5 compiler could understand classes etc, but it dod not use classes to represent any Windows processes.
|
|
|
|
|
Anthony Appleyard wrote: but it dod not use classes to represent any Windows processes.
It did if you used OWL, just like VC++ does when you use MFC.
Mark
|
|
|
|
|
Anthony Appleyard wrote: so I can see how to program for Windows using classes (e.g. the class called "Window")?
Where did you see a class called "Window"?
As mentioned by Hamid, Visual C++ (non-Express versions) comes with the MFC
library which is a class-based framework wrapping the Win32 APIs.
If MFC is what you are interested in, you can build a fully functional
MFC application with the project wizards. See File/New/Project... in
Visual Studio.
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
I have got my program project working. With thanks to all who have answered my queries. (I have the free download version of Visual C++ 2008.) (It is like Windows Character Map, but its display is much bigger and clearer, and it can handle all 65536 Unicode characters.) This query arises: Can the resulting ---.exe file run on another computer? Or what needs to be doing to it or to be uploaded along with it?
|
|
|
|
|
Im sorry understand what you said?
|
|
|
|
|
|
Hi All,
I have very serious problem regarding using DllMain() function in my application.I have created MFC Activex Control in VS2005.
I have created one .cpp file in that I want to use DllMain() function as below....
BOOL WINAPI DllMain (HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)<br />
{<br />
}
But when I use this function (At least these three lines.. ) I got an error like below....
Hooking.obj : error LNK2005: _DllMain@12 already defined in mfcs80ud.lib(dllmodul.obj)<br />
ActivexVS05.ocx : fatal error LNK1169: one or more multiply defined symbols found
I have searched for this error in google but I could not found the solution.
If you have any suggetion and solution then please reply me.
Thanks in Advance.
|
|
|
|
|
MFC implements DllMain for you. Override the InitInstance method instead.
Read the DllMain[^] article very carefully, and the Best Practices for Creating DLLs[^] white paper. Note particularly that calling MFC methods may not be safe if MFC has not yet initialised, if you're using MFC in a shared DLL.
In general I would recommend avoiding any initialisation steps in DllMain and instead perform them in the class itself (perhaps in the constructor).
DoEvents: Generating unexpected recursion since 1991
|
|
|
|
|
Hi,,
Sorry for the very late reply.
Thank you very much for reply.I have read the article as you told and I have solved this problem but now I am facing new problem regarding this topic.
Now I am using below code for the my project purpose using Dllmain().Here I have created one DLL in that I am using this function.In this DLL what happens that this DLL checks for screen update and mouse update on the desktop and sends messsages to my MFC Activex Control (which is another project in the same Solution).
<br />
BOOL WINAPI DllMain (HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)<br />
{<br />
hInstance = (HINSTANCE)hInst;<br />
<br />
<br />
return TRUE;<br />
}<br />
And now problem is when I run my Activex from Activex control test Container then whenever this test container is active on top of the desktop then messages(like Scrren update,,Mouse update)are peeked up by Activex control application but when any other window is active then these messages are not peeked by Activex.
Is the problem with this hInstance which get the instance of the window in which My Activex is running???
I ahve tested running my activex in explorer but the same problem exists.
I peeked up these messages from my Activex by below code....
<br />
MSG msg;<br />
while(1)<br />
{<br />
if(!PeekMessage(&msg,m_desktop->m_hwnd,NULL,NULL,PM_REMOVE))<br />
{<br />
if(!m_desktop->CheckUpdate())<br />
break;<br />
if (!WaitMessage())<br />
{<br />
AfxMessageBox(CString("WaitMessage Failed"));<br />
break;<br />
}<br />
}<br />
else if(msg.message == SCREEN_UPDATE)<br />
{<br />
}<br />
else if(msg.message == MOUSE_UPDATE)<br />
{<br />
}<br />
<br />
}<br />
Please give me any suggetion if you have any idea or ask me if you have any more quetions.
Thanks in Advance.
Ashish Bhatt
|
|
|
|
|
Also, study this to make sure you're using the correct form of MFC DLL
and initializing it properly...
Kinds of DLLs[^]
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
For example, there are two images with the same size.
One is a normal pic, the other is a mask bitmap.
The colors in the mask one are composed with black and white (including gray).
Now let gray level become transparency.
Put the mask bitmap onto the normal one, and get the image.
How to do it with GDI+?
Thnaks.
|
|
|
|
|
AFAIK, GDI+ doesn't have built-in code for image masks. Transparency is handled with alpha
channel instead.
You could step through the pixel values of the mask and based on each value, adjust the
alpha value of each pixel in the other bitmap.
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Yes, I'll do this way.
Thanks.
|
|
|
|
|
I want to init CListCtrl, m_hWnd of CListCtrl must be available,
where to put the init code?
|
|
|
|
|
Can you reformulate you question (give more details)?
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
|
|
|
|
|
class CMyDialogBar:public CDialogBar
{
...
public:
CMyListCtrl m_list;
...
}
CMyListCtrl::OnCreate()
{
}
|
|
|
|
|
Does your CMyListCtrl inherits from CListCtrl?
Can you detail a little more (sorry for the insistence)?
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
|
|
|
|
|
How did you make your listbox? visual or dynamic
|
|
|
|