|
I don't think there's some special message - when your client area is invalidated after dragging, the window receives WM_PAINT/WM_ERASEBKGND. Are you sure your handlers are OK?
Tomasz Sowinski -- http://www.shooltz.com.pl
|
|
|
|
|
Well, the thing was, OnDraw only draws when necessary, and I had no means to detect window movement over the client. Erase won't occur either as I had overriden it. So the end result was the ghoust images of windows being dragged over it. Isn't there a message to detect a child of the client over it? Like when tool bar floating over client, how do I detect that sort of floating window getting dragged around within client?
|
|
|
|
|
Would it help if you put a little code in your OnEraseBkgnd to check if your app has the mouse or focus? If a call to GetCapture, e.g., reveals that the window with the mouse capture is not yours, there's a good chance that the WM_ERASEBKND is one you should act on.
|
|
|
|
|
Hi, everyone.
I have got the problem,the problem is that I made MDI (RichEditView based class) application n i also created a dialog on the MDI, But i am not understanding how can i pass the data from dialog to CRichEditView.However i gave the dialog, base class to the same existing view.Plz explain it to me in detail...
Thanx.
|
|
|
|
|
How do I copy an Icon (I got a handle to HICON) into the clipboard?
Thanks,
Jignesh
|
|
|
|
|
I am working on a project where I would need to remove a file safely (owerwrite the file data with other). How can I access the cluster directly within a MFC program?
|
|
|
|
|
I'm making a couple of assumptions here, so if this isn't what you're looking for provide additional detail...
You can create a CFile, and open it shareExclusive, that will prevent others from working with it or reading it while you have it open.
You can then Seek to a specific location within the file, and write your new data to that spot, then close the file.
Check out the documentation for CFile.
Hope this helps
Jeff
|
|
|
|
|
Hi!
Recently, I've figured out a method to build a linked list of items
in an .exe before WinMain gets called. The method relies on the fact
that a global instance of a class will always call it's contructor
before WinMain is called. Some example code of what I'm doing:
cLinkedList g_List; // my linkedlist of data. it's global and currently empty
class cListBuilder // this class will add a new node in the linkedlist
// when a variable of this class is declared
{
cListBuilder()
{
cData* poData = new cData;
g_List.AddNode("NodeName", poData);
}
}
cListBuilder ListBuilder; // because this is a global, it's constructor is
// called first, right before WinMain, filling the
// linked list with one node.
int WinMain()
{
// by the time we get here, m_gList has one element
printf("NumNodes: %d\n", g_List.GetNumNodes());
}
I just made up the code from memory, so it might not compile out of the box.
Anyway, this works inside an .exe, but it doesn't when I try this method inside
a DLL. The implementation differences being that:
1) g_List is now declared in it's own seperate .cpp file (gList.cpp)
2) WinMain is replaced by DllMain (duh). The function is now seperated into
it's own file, DllMain.cpp. It calls "extern cLinkedList g_List" to have
access to the list.
3) the decleration of cListBuilder is in it's own .h as well. (cListBuilder.h) It
gets g_List by calling "extern cLinkedList g_List", the same way DllMain.cpp does
So now, the project looks like this:
-- gList.cpp -------
cLinkedList g_List;
-- End gList.cpp ---
-- cListBuilder.h ------
extern cLinkedList g_List; // the g_List *should* be coming from gList.cpp
class cListBuilder // this class will add a new node in the linkedlist
// when a variable of this class is declared
{
cListBuilder()
{
cData* poData = new cData;
g_List.AddNode("NodeName", poData);
}
}
static cListBuilder ListBuilder; // now declared static to have it persist
-- End cListBuilder.h --
-- DllMain.cpp ---------
extern cLinkedList g_List;
int DllMain()
{
// g_List *should* have one node in it when it reaches here.
}
-- End DllMain.cpp -----
That's pretty much how my project looks like right now. It's very
similar to what I was doing before in the .exe. The problem is
that by the time I reach DllMain, the linkedlist is empty even
though cListBuilder::cListBuilder() was called. I placed a break
point inside the constructor, and it definately stops there. The
constructor does add the new node to the linkedlist without fail.
But, like I said, by the time I reach DllMain, it's like I never
touched g_List. It's like the actions I did inside cListBuilder::
cListBuilder() are completely forgotten as soon as I go out of
the scope of cListBuilder.h. And the g_List's destructor never
gets called, either, so it's not like it actually empties the list.
The problem is compounded when I add more files like cListBuilder
that try to add more nodes inside g_List. For example, if I added
a new file to the project called cListBuilder2.h that looked like:
-- cListBuilder2.h ------
extern cLinkedList g_List; // the g_List *should* be coming from gList.cpp
class cListBuilder2
{
cListBuilder2()
{
cData* poData = new cData;
g_List.AddNode("NodeName2", poData);
}
}
static cListBuilder2 ListBuilder2;
-- End cListBuilder2.h --
So, because I now have ListBuilder and ListBuilder2 declared as global static
variables, they both would try to add a node into g_List. But the weird thing
is that if ListBuilder's constructor gets called first and adds a node, by the
time ListBuilder2's constructor is called, the list is magically empty again.
Then ListBuilder2 would add it's own node and then by the time we reach DllMain,
the list is empty once more.
I can't figure out why this doesn't work in a DLL when it works perfectly in
an .exe. I don't know how Dlls handle global variables differently than
executables.
I'm not quite sure if I actually explained the problem really well. It's a pretty
weird situation, if you ask me. So, if anybody has any insight into this, it would
be really helpful. I can try to clear this up some more, if I can.
Thanks for taking the time to read this monster post.
Steve
wrlddomprod@hotmail.com
|
|
|
|
|
Hi,
It's very late here, so I have to be brief: probably you hit the problem with order of constructors called. Your list and list builders are global. There's no way to guarantee that list c'tor will be invoked first. Just put the breakpoints in list constructor to check it out.
Hope it helps and goodnight
Tomasz Sowinski -- http://www.shooltz.com.pl
|
|
|
|
|
I think its a problem of visibility. Now that you have several declarations of g_List, there's some subtlety of the linkage that isn't tying them to one object. Almost as if there's no defining object, though intuitively I would think there is (the one without the extern).
To test, you might look at the address of the g_List at the points when g_List.AddNode is called. If you get different addrs, I'd say its not a DLL specific problem, but rather falls under the category of storage class specifiers.
-----
#include "just_a_theory_disclaimer.h"
|
|
|
|
|
Hey!
I checked it out. It's the same address all around. So they are pointing
to the same instance of g_List.
Also, it looks like the g_List's contructor only gets called before
DllMain(), even though it AddNode() gets called twice (in cListBuilder
and cListBuilder2). I just find that odd.
What I don't understand is how this method seems to work within an .exe
but not inside a DLL.
Another question would be, is there another way to accomplish this?
The whole goal of this is to have a linkedlist of information that
can be got from a DLL, but the linkedlist can only be built inside
.h files. Almost like building a linkedlist at compile time.
The only place I've seen this done is inside Monolith's Lithtech 3d engine.
They use a similar method to build an array of actor classes that can
be exported from a DLL so that the game client knows about what kind of
objects/enemies it can create. For them, to add a new class to the
array they just create the .cpp and the. h file for the new actor class and
call various macros in the actor's .h file. These macros, from what I've
understood, automatically add the new actor class to this actor "database".
They don't need to modify any other file, or modify any "factory" functions
to able to create an instance of the new actor class. I find their method
to be incredibly elegant, but I just can't totally figure out how they did it.
To find out what I mean, you can download the source code to Shogo in the
"files" section of PlanetShogo.com. Look at any of the actor classes inside
of the "server/objects" workspace, and you'll see what I mean.
Shawn
|
|
|
|
|
The problem is the 'order of construction' problem for global variables.
If the global/static 'cListBuilder1' and 'cListBuilder2' objects are constructed BEFORE the global 'g_list' object, then the calls to 'g_list.AddNode' are most likely failing (because g_list does not yet exist, so you can't add to it). Note that this means you can call a member function of an object that has not yet been constructed!! This is perfectly valid C++ code, but not likely to be what you want. You are probably lucky that you are getting just 'failed function call' - often this behaviour will lead to crashes.
Why would the 'listBuilder' objects be created before 'g_list'? Well, since they are all global objects in different compilation units, the order of construction is undefined - the compiler/linker can schedule the calls to the required constructors in any order they like - as long as all global objects get constructed before the 'main' is called. What makes this kind of problem even worse is that the order of construciton can change simply by adding a new global variable into some file in the project - in this case, the compiler/linker can totaly change the order of global constructions, causing previously "working" code to now fail.
The solution is to use "Create On First Use" semantics for the g_list object. This means you don;t make it a global - you create it the first time it is used (the first call to "AddNode" from a global 'cListBuilder' object constructor, for example. To implement this, put the variable into a function, like this :
cLinkedList& g_List()
{
static cLinkedList theList_;
return theList_;
}
Now, your constructors for the cListBuilder become :
class cListBuilder {
cListBuilder()
{
cData* poData = new CData;
g_list().AddNode("NodeName", poData);
}
};
Since the ListBuilder construtor is now calling a function 'g_list()' rather than a variable 'g_list' you do not have to worry about the order of construction. The rules for static variables inside functions means that the internal 'theList_' object is created only once, and only when the function is called. The function cannot be called without creating the static variable, unlike memeber functions of global variables (which can be called from constructors of other objects before the 'owning' object's constructor!).
I think the reason this was working in an EXE and not the DLL is just blind luck - although, you should note that if all 3 global varaibles are in the same compilation unit (eg, the same cpp file) then the order of construction is normally fixed at the order of the variable declarations (but I'm not sure if the language guarantees this!)
|
|
|
|
|
Aaaah, now I get it. I tried your suggestion and now it works like
a charm (woohoo!) Thanks for the help!
Steve The Plant
|
|
|
|
|
Hello all,
I know that when you export a function from a dll that uses MFC dynamicaly, you have to use the AFX_MANAGE_STATE() macro.
If you export a class from a dll that links to MFC dynamically , do you have to use the AFX_MANAGE_STATE() macro in each member function of the class? If so, what about protected and private functions that won't be called by the client app???
Thanks!
|
|
|
|
|
Hi all,
I'm in the process of writing a Text Viewer application. Notepad does not open large files, and Wordpad opens them but reads them all into RAM and brings the OS to its knees with the swap files, etc.
What I want to do is to open a text file and just read in the portion of the file that should be showing (and some extra for caching, but not terribly urgent right now). Then as the user runs the scroll bar, I would redraw the text that I need to redraw.
A future addition to this program will be for other file types, so I wil have a class to work with Text drawing, and then add other classes as necessary to draw TIFF's or our own file format, etc.
Unfortunately, as I work with this, I keep running into problems with MFC.
I'm working with MS Visual C++ 6.0, SP 4, MFC 6.
Using CScrollView I can print the file, and print preview, but when I try to scroll the file on the screen, it chops off the top, or the bottom, or chops the bottom off lines of text, etc.
Any thoughts about a good way to go about this? Is ScrollView too much of a "helper" if you're not planning on reading the whole file into RAM? Would CView be better? Should I just scrap MFC and write it using the APIs myself?
Any thoughts would be appreciated.
Jeff
|
|
|
|
|
Oops, additional info.
I'm currently working on Windows 98, but any solution would need to work on Windows NT and Windows 2000 as well.
Thanks for any info
Jeff
|
|
|
|
|
Thanks for who that answer me on this question.
But I have still problem with it.
my code is so :
-------------------------------------------------------
CFile file;
CFileException ex;
if(!file.open(str_pathName, CFile::modeRead, &ex))
{
//error
}
else
{
//open
}
.
-------------------------------------------------------------------------
when I run it I gets this error:
: error C2039: 'open' : is not a member of 'CFile'
c:\program files\microsoft visual studio\vc98\mfc\include\afx.h(1202) : see declaration of 'CFile'
Error executing cl.exe
-----------------------------------------------------------------------------
------ WHY ???????????????????????
|
|
|
|
|
Is Open, no open, with Capital 'O'
Cheers!!!!
Carlos Antollini.
|
|
|
|
|
detail , please!
|
|
|
|
|
Incorrect Case:
file.open(str_pathName, CFile::modeRead, &ex)
Should be:
file.Open(str_pathName, CFile::modeRead, &ex)
|
|
|
|
|
thank you very much !!!!!!!!!!!!!!!!!!!!!!!
|
|
|
|
|
Hi *.*
I have written an MFC application in MS Visual C++6. Now I want to compile it with a different compiler but the one from MS. Is there a way to compile the whole project with borland's c++ compiler?
Are there any other good (or even better) compilers you can recommend?
thanks
|
|
|
|
|
I once used the Borland CPP Builder 4 VC++ Project Conversion Utility on a simple VC6 MDI project just to test. Worked well. My version of Builder has MFC files that corespond to VC5, but that wasn't a big issue for the simple test app.
|
|
|
|
|
I'm looking for some documentation on serial port communication in VC++. Does MFC support it?
- john
|
|
|
|
|
Never mind, I'm a moron. However it wouldn't let me delete my previous message, so I'm just saying I figured it out (and feel stupid)
|
|
|
|
|