Could you describe this step in more detailed fashion? Sure - First I have a LRESULT CALLBACK MyWndProc() function that I've set up to process messages, I'll describe it more specificaly in a moment. I create a CButton and then call ::SetClassLong using GCL_WNDPROC as the argument and then I store the return value for use in MyWndProc. Inside MyWndProc, I watch for WM_PAINT messages (because this is the first message that gets sent after MFC has actually added it's member variables to the permanent message map - and because after I subclass, WM_PAINT won't get sent anymore for my ownerdrawn buttons) and when I find one, I create a new CoolButton and tell it to subclass the Wnd. It's in this step that I would unattach the member CButton from the application's permanent message map if I had access to it (In fact, the unattach is essential if this code is to be run from the application itself since a handle map can not have two MFC classes pointing to the same window handle). Was this what you were looking for? WM_KILLFOCUS is sent (not posted through message loop/pump). My bad - in any case, it ends up going through my WndProc and then being sent on to the default one, which is what causes the crash when a member variable exists. Thanks, Dave
Dave Glick
Posts
-
MFC Regular DLLs and Handle Maps -
Drag and Drop TextHowdy, I think you would need to override several mouse functions in your Label class to do the following: OnLButtonDown: Track when the user clicks and if they have the left button down so that you can know what to do when they move the mouse OnLButtonUp: Again, use this to remember the mouse button state OnMouseMove: Inside here test to find out if the mouse button is down and if so, use MoveWindow to move your window to the same coordinates as the mouse is moving to I think that should do it, but this is just a guess. Hope it gives you a good direction to start looking... Dave
-
How to use WM_COPY?Hey, I think the problem might be in your m_hWnd variable. The WM_COPY message should get sent to the window from which you want the data - in this case, the Edit box from the other application. It can be a little tricky to get your hands on this hWnd. My suggestion would be to use ::FindWindow to locate the window in question (you'll need the class name, which is probably "EDIT", and also the window name, which you can get by using Spy++). Hope that helps! Dave
-
MFC Regular DLLs and Handle MapsHi all, I've got a very difficult problem that I've spent several weeks trying to figure out. I think I finnaly know the issues, but not how to solve them. I humbley submit my predicament to you fine folks here on code project to see if anyone has any insight... Let me describe the setup: -I have a MFC regular DLL statically linked to MFC (I don't know what language or environment my DLL will be used from and I want to support the broadest range). -This DLL globaly subclasses certain types of GUI objects. For the purpose of providing an example, I'll use the windows BUTTON api class for illustration here. -The DLL calls ::SetClassLong and does some mumbo-jumbo to override all BUTTON WndProcs and set them to be ownerdrawn. At the same time, I subclass all of them to a special CoolButton class derived from the MFC CButton. -I also subclass all Dialogs so that I can intercept WM_DRAWITEM messages and send them to the child based on my handle map rather than the app's (because the app doesn't know about my subclassed CoolButtons, it would send the DrawItem message to CButtons which would assert because the DrawItem function hasn't been overridden). Everyone still with me :) Everything works perfectly from other languages and from within MFC except in one case, and this is the root of the problem: When a button on a dialog has had a member variable of type CButton declared from within the calling application, I ASSERT on a call to CButton::DrawItem (because no override is present) at random times (for example right after a WM_KILLFOCUS message). I think this happens because the message pump looks like this: -Send WM_KILLFOCUS to the AfxWndProc -AfxWndProc sends it down the pipe -I intercept (remember I'm looking for WM_DRAWITEM messages for the parent so I've inserted myself here) -I want to do the default action, so I pass the WM_FILLFOCUS to the old WndProc (which I got from my call to ::SetClassLong) -The old WndProc does the default OnKillFocus action - everything works great up to here. -If no member CButton variable has been declared, the old WndProc sends a WM_DRAWITEM to the parent, I intercept it, take action, and viola, everything works great! If a member CButton has been declared, the default WndProc bypasses the top level windows message routing routine, I never see the WM_DRAWITEM message, and by looking up the CButton member from the application's permanent handle map it calls the CButton::DrawItem and I crash :( The solution, as I see it, is to replace the CButton member variab
-
Closing initial Document in MDINo problem... Try looking into AfxGetApp() -Dave
-
Handler for Highlighting TextHowdy all, I've been stumped on something for a while now. I've got a CEdit subclass that I'm writing to change all sorts of nifty colors, but I can't seem to change the color (usually blue) that gets drawn as the background for text that gets highlighted. I've tried setting a breakpoint in the OnChildNotify function (which as I understand gets ALL messages) but it doesn't even trigger when I highlight text. Is changing the behavior something that I'm unable to do (maybe it's internal to windows)? Any ideas - if nothing else I'd just like to get to the bottom of it and satisfy my curious mind... Thanks, Dave
-
Help with ownerdrawn CListBox classThanks Tomasz, that's exactly what I needed. Just swap out the brush in there and it works perfectly... Dave
-
Authentification on Web ServerThis may be kind of obvious and thus a stupid question, but did you try connection to the page the form was on or the page the form points to? -Dave
-
Help with ownerdrawn CListBox classHello, I could use a little help with a CListBox class I'm writing. I've been putting all sorts of code in the DrawItem function to make the List Box nice and pretty. Unfortunatly, I can't seem to change the background of the list box unless there are items in it. I.e., I've got three items in a list box that holds 10. The first three items will be my modified background color, but then the rest of the list box which isn't holding any items is just the default white. Another problem, probably related, is that I wanted to make the ListBox display the disabled color even when it contains no items (you'll noticed the default CListBox class gives no indication it's disabled unless there are items in it). Any thoughs/ideas? -Dave
-
Closing initial Document in MDITo answer your second question the way I've always done it is as follows: 1) Find the document template (each template is a different doc/view class - you probably only have one in which case just ignore the last two lines)... POSITION DocPosition; DocPosition = GetFirstDocTemplatePosition(); CDocTemplate* first_template = GetNextDocTemplate(DocPosition); CDocTemplate* second_template = GetNextDocTemplate(DocPosition); CDocTemplate* third_template = GetNextDocTemplate(DocPosition); 2) Create a new file CSomethingDoc* newdoc = STATIC_DOWNCAST(CSomethingDoc, first_template->CreateNewDocument()); 3) Do any work in the Document class you need to and then show the new file CFrameWnd* newframe = first_template->CreateNewFrame(newdoc, NULL); newframe->InitialUpdateFrame(newdoc, TRUE); Hope that helps. -Dave
-
Modaless Dialog BoxI have a need for this quite often, and while I haven't gotten around to writing my own class to do it, I know of one that works very well. It's called PassiveDialog and comes with the ITCLib package(http://devcentral.iftech.com). If I look at the code (just to get ideas) I find they've overridden the DoModal function: ... TRY { // create modeless dialog AfxHookWindowCreate(this); if (CreateDlgIndirect(lpDialogTemplate, CWnd::FromHandle(m_hWndParent), hInst)) { if (m_nFlags & WF_CONTINUEMODAL) { m_nFlags |= WF_MODALLOOP; ShowWindow(SW_SHOWNORMAL); UpdateWindow(); Pulse(); } } } ... And created a new Pulse function to pass messages back to the calling code: ... // Check to see if we can do idle work while (bIdle && !::PeekMessage(pMsg, NULL, NULL, NULL, PM_NOREMOVE)) { if (!(dwFlags & MLF_NOIDLEMSG) && m_hWndParent && lIdleCount == 0) { ::SendMessage(m_hWndParent, WM_ENTERIDLE, MSGF_DIALOGBOX, (LPARAM)m_hWnd); } if ((dwFlags & MLF_NOKICKIDLE) || !SendMessage(WM_KICKIDLE, MSGF_DIALOGBOX, lIdleCount++)) { bIdle = FALSE; } } ... For more info, just go download the library. Keep in mind, though, that the code is ©. Hope this helps! -Dave