|
The class needs not be derived from CWnd, but you need MFC to convert a HWND to CWnd
modified 12-Sep-18 21:01pm.
|
|
|
|
|
But in CMyWinApp
CWnd::FromHandle() is unavailable.
But I need to convert a handle to a pointer.
R.
|
|
|
|
|
a pointer to what?
Alcohol is the anesthesia by which we endure the operation of life.
-- George Bernard Shaw
|
|
|
|
|
CWnd::FromHandle() is a static member
function. It will, if necessary, create
a temporary CWnd object and return a
pointer to that. Like so:
CWnd* pTmpWnd=CWnd::FromHandle(hSomeWnd);
Call it from anywhere.
|
|
|
|
|
Scott,
thanks for the solution!
R.
|
|
|
|
|
A CWnd is a wrapper for a HWND, and if you're in Win32, you won't have anything that takes or uses a CWnd. Perhaps if you explained what you were trying to do, I suspect the problem is your approach in general, and not the specific question you're asking.
Christian
Hey, at least Logo had, at it's inception, a mechanical turtle. VB has always lacked even that... - Shog9 04-09-2002
During last 10 years, with invention of VB and similar programming environments, every ill-educated moron became able to develop software. - Alex E. - 12-Sept-2002
|
|
|
|
|
Christian,
I plan to write an app which connects to external running instances of IE. This is a dialog based app with MFC support. However, the actual work
(HTML parsing) is done in my CMyWinApp class, in my dialog I only handle the settings.
SHDocVw::IShellWindow returns all IWebBrowser pointers, and SHDocVw::IWebBrowser2::get_HWND returns the handle of an external IE Window, and I wanna make the topmost of them the parent
window of my dialog which should be done when constructing the dialog.
(CMyDialog dlg(pWnd)). Since the dialog is constructed in CMyWinApp in case of an MFC application, I have to convert the extracted HWND handle to a CWnd* pointer. Fortunately, CWnd::FromHandle is a static
function, so I can make this conversion in CMyWinApp, too. Since I didn't know that, I couldn't use it.
10x to Scott for pointing this out.
10x to you, too, for helping to see clear in this question.
R.
|
|
|
|
|
I want to know how to put a background bitmap (like a watermark)in my CEdit/CRichEdit ctrl. Can somebody help?
|
|
|
|
|
CRichEdit has a way to set its background as transparent, but i have never used it so can't tell how to do it. You could set the container's background and place the CRichEdit object over.
Otherwise, derive a class CNewEdit from CEdit and override as follows:
HBRUSH CNewEdit::CtlColor(CDC* pDC, UINT nCtlColor)
{
pDC->SetBkMode(TRANSPARENT);
return (HBRUSH)GetStockObject(WHITE_BRUSH);
}
BOOL CNewEdit::OnEraseBkgnd(CDC* pDC)
{
pDC->BitBltStuff();
return 0;
}
rechi
|
|
|
|
|
Hi
Can I assume that if some application is using some dll, this dll will be in memory till the application terminates? I want to store some data in dll, so this is quite important for me. I'm also not sure if there is always one instance of dll, shared amongst all applications using the dll (I want to share data stored in dll between applications). Thanks in advance for the answer.
Greetings
Mariusz Popiolek
|
|
|
|
|
No, you cannot assume that. DLLs are not always loaded at the start of an application and then removed from memory at the end of the application. An app can call LoadLibrary() to grab your DLL and then FreeLibrary() as soon as it's done with it. There is nothing stopping an app from doing this.
A DLL is not a self-standing process. It is only a collection of code and variable definitions with no execution startup code. When an application loads a DLL, all of the DLL's static data variables (eg. global) are created in the calling process's address space, in addition to a table of function pointers. These variables are unique for every process that might load the DLL. The actual code inside a DLL is shared between processes, since it's simply a set of instructions on how to go about it's business.
If you allocate memory inside a DLL function, that block of memory is located within the heap of the calling application that loaded the DLL and called the function. You cannot share memory between processes by just creating a global variable (or a static variable inside a function) and reading/writing it in the calling app. Those variables simply can't be shared between processes by default.
That said, there are ways to go about the task of sharing memory. You can create a shared memory block within your DLL code that is open to any and all applications that want to use it. Technically, you don't really need a DLL to do this, but it's helpful for having a common codebase with which to create and get at the memory object.
Take a look at these functions:
CreateFileMapping()
MapViewOfFile()
The docs on these functions indicate they're used for mapping files into memory. Which is true. But if you pass INVALID_HANDLE_VALUE to CreateFileMapping(), you can build a memory object with a unique name that can then be "mapped" by any process that chooses to do so. That's where MapViewOfFile() comes in.
Something like this:
LPVOID CreateABuffer( DWORD SizeOfYourBuffer )
{
HANDLE hMemory = CreateFileMapping(
(HANDLE)0xFFFFFFFF,
NULL,
PAGE_READWRITE,
0,
SizeOfYourBuffer,
"Name you want to call it"
);
if( hMemory == NULL )
{
return NULL or do something creative;
}
LPVOID lpMemory = MapViewOfFile(
hMemory,
FILE_MAP_WRITE,
0,
0,
SizeOfYourBuffer
);
CloseHandle( hMemory );
if( lpMemory == NULL )
{
return NULL;
}
return lpMemory;
}
Here's what happens. The very first call to CreateFileMapping() will allocate the shared memory block. So long as that buffer still has handles open to it, it will not be wiped away. Subsequent calls to CreateFileMapping() with the same name will simply get a pointer to that shared block and will not create a new buffer. MapViewOfFile() is required to actually get a useful pointer to the memory, since CreateFileMapping() returns a HANDLE.
You will need to also call UnMapViewOfFile() when you're done with the buffer. Internally, the shared memory block has a reference counter that increments every time a calling process maps into it. You also have to close the handle to the buffer, as that is also counted and the buffer will not be freed until all handle references are removed. I've done that in the above code. You may wonder why it's done immediately after the MapViewOfFile() command. I did it there so as to not have to worry about cleanup. This won't blow away the buffer; so long as the mapping was successful, the reference counter was incremented and the buffer will stay in memory.
That's it for sharing data between apps inside your DLL. Keeping it alive until the app terminates would have to be enforced by the people writing the application; you can't specify that yourself. A solution there would be to create your own dummy EXE that loads the DLL and it hangs around forever, like an NT service or something.
Ty
"The significant problems we face cannot be solved at the same level of thinking we were at when we created them." -Albert Einstein
|
|
|
|
|
Thanks, man. Your answer is very comprehensible, but I don't agree with one statement. MFC dlls have startup code and I wonder whether normal dlls can have too (let's imagine global variable of some type with constructor, but I'm not sure if this will be working).
Greetings
Mariusz Popiolek
|
|
|
|
|
Sorry... by "startup code" I meant that DLLs are not standalone programs. You can't fire them up and have them run by themselves because they lack the code to do so. You are correct, however; all DLLs have an initialization routine (DLLMain) and all static variables are constructed when the DLL is first loaded.
Remember that MFC is only a wrapper around the Win32 API... under the hood, MFC DLLs are just regular DLLs with the benefit that all of the MFC initialization stuff is written for you (there is a ton of it.) Take a look at the source files VC98\MFC\SRC\DLLINIT.cpp and DLLMODUL.CPP for just a couple samples of DLLMain.
Regardless of there being startup code, you simply cannot share a global variable between applications using the same DLL. As I mentioned in the previous post, you have to create a file mapping object in order to create a block of memory that is shareable between processes. I have a sample application that does this if you're interested in some actual usable code. I've written a couple applications in the past that use this technique.
Ty
"The significant problems we face cannot be solved at the same level of thinking we were at when we created them." -Albert Einstein
|
|
|
|
|
As I've read in my previous post "Callback and Assembly", there are more then one way to get it done. It's about a Callback procedure in a class.
The following methods I came accross:
Static with a pointer to the class to call the non-static member
Thunking, as is done in ATL with use of assembly
Convert thiscall to a callback, but it's highly inportable.
Attaching a class and a HWND into a Dynamic Array, and use a global Callback that calls the right class (use virtual member functions)
I'm curious, how many more great ways are there to do an OO-callback
LPCTSTR Dutch = TEXT("Double Dutch ");
|
|
|
|
|
Thunking/converting thiscall to callback without using fancy assembler tricks, but adapter objects and C++ standard language features as described in my article Use member functions for C-style callbacks and threads - a general solution.
The article focusses on dealing with the typical Win32 API callbacks, however, the underlaying technique is generic and portable.
--
Daniel Lohmann
http://www.losoft.de
(Hey, this page is worth looking! You can find some free and handy NT tools there )
|
|
|
|
|
I have
while (!m_db1.m_pRecordset->GetadoEOF ())
{
int n = m_db3.m_pRecordset->RecordCount;
m_db3.m_pRecordset->AddNew();
SomeStuffThatAddsAValidRecordToDb3();
m_db1.m_pRecordset->MoveNext();
}
The first time through, when there were zero records in m_db3, there is no problem. Then it advances m_db1 by 1, and gets back to the top of the while. This time when it tries to execute AddNew it crashes. Incidentally, if I move the AddNew() out (just
as a test), then it chokes on both UpDate(), or UpdateBatch(). What am I doing wrong?
Thanks very much
ns
|
|
|
|
|
I tracked it to:
inline HRESULT Recordset15::AddNew ( const _variant_t & FieldList, const _variant_t & Values ) {
HRESULT _hr = raw_AddNew(FieldList, Values);
if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this));
return _hr;
}
but the odd thing is I'm using it like AddNew() with no arguments. It compiles fine .Suggestions?
If I did make a fieldlist and a values variable what are these? Arrays?
thanks,
ns
|
|
|
|
|
I have a menu in my dialog and when the user does something it needs to use a different menu. What I do:
<br />
CMenu newMenu;<br />
newMenu.LoadMenu( IDR_NEW_MENU );<br />
ASSERT(newMenu);<br />
SetMenu(NULL);<br />
SetMenu( &newMenu );<br />
That displays the new menu, however you can't click on the menu at all. How can I fix this?
There's always one more bug.
|
|
|
|
|
When newMenu goes out of scope, it destroys the menu object as well. Move it to a member variable of the dialog class.
--Mike--
"I'd rather you just give me a fish today, because even if you teach me how to fish, I won't do it. I'm lazy." -- Nish
Just released - 1ClickPicGrabber - Grab & organize pictures from your favorite web pages, with 1 click!
My really out-of-date homepage
Sonork-100.19012 Acid_Helm
|
|
|
|
|
I have a MFC framework like this .
I have a CFormView ,a Document class and another CView class in my MDI application .
Initially I want to show the CFormView class as the default and when the user clicks a ToolBar button I want to show (invoke) the CView class to draw some stuff .
The thing that I have in mind is to have 2 MDIDocumentTemplates added to my application .
But how do i switch Between views and how do I add to the Documenttemplates ?
For a better understanding of my problem consider the following :
My FormView contains XML data organized in CTreeCtrl .
In the View i want to draw an Object Tree based on data in the TreeCtrl .
I am really getting confused over this . Please help
|
|
|
|
|
IMHO you shouldn't have 2 document templates but only one. It's the basis of the document-view architecture: for one document containing the data you may have severals views of the same document with different graphical showings. Have a look to
CDocument::AddView[^]
HTH,
K.
Influence of the Evil, Influence of the Good, which of both will go further?
Wobbly destinies, dubious dreams, which of both is good for nothing?
L'emprise du Mal, l'emprise du Bien, lequel des deux ira l'plus loin?
Destins bancals, rêves incertains, lequel des deux est bon à rien?
Come On Boys/Ludwig Von 88
|
|
|
|
|
Hi all.. I downloaded libtiff tiff library.
and I have to create .lib file.
the instruction said that I can use command "nmake /f makefile.vc"
but I the command "nmake" is unknown.. even I'm in the vc++ directory( where vc++6.0 installed).
How can I use vc++ compiler to create lib file.
I tried, file->new->project->win32 static library-> no MFC support.
then I included all the .c and .h files then I clicked build->create lib file. but got lots linking errors.
does anyone know how to create libtiff.lib file?
thanks
|
|
|
|
|
|
thanks I didn't see that b4..
|
|
|
|
|
Hi guys !
Let's say I know how to get the user selection in a multiple selection list box.
Now, how can I take this buffer of text and copy it to the clipboard so someone can copy it to notepad for example ?
I received great help before , waiting for more
Shay Harel
|
|
|
|
|