|
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
|
|
|
|
|
Use an OLE Clipboard for sending and receiving text data type. I recommend MFC. Otherwise, you are looking implementing your own COM solution.
Kuphryn
|
|
|
|
|
ummmmm
cant he just do GetText() and send it to the clipboard?
"... and so i said to him ... if it don't dance (or code) and you can't eat it either f**k it or throw it away" biz stuff about me
|
|
|
|
|
Thanks,
A small example will be apprtiated.
Shay
|
|
|
|
|
Here is on solution to copy text to the clipboard via MFC wrapper to OLE Clipboard.
-----
CString szText(TEXT("October"));
HANDLE cbData = ::GlobalAlloc(GMEM_MOVEABLE, szText.size() + 1);
PTSTR pData = static_cast<ptstr>(::GlobalLock(cbData));
_tcscpy(pData, szText.data());
::GlobalUnlock(cbData);
COleDataSource *pODS = new COleDataSource;
pODS->CacheGlobalData(CF_TEXT, cbData);
pODS->SetClipboard();
-----
Kuphryn
|
|
|
|
|
HI
When I try to :
COleDataSource *pODS = new COleDataSource;
I get a comiple error of undeclared identifier.
Do I have to #include anything out of the ordinary to use the ole clipboard ?
Thanks once again for you effort, I appreciate it.
Shay
|
|
|
|
|
Greetings...
In a dialog box I am creating one cutsom drawn grid, now when the user presses TAB in the dialog box, the focus is changed to all other control except the Grid ?
I belive since I am creating Grid in the WM_INITDIALOG message of the dialog box the tab is not making focus move to the GRID ?
How do I make the focus move to the grid ?
Thanks
Ritesh
|
|
|
|
|
Try this
form the menu bar when you are in dialog edit screen chhose:Layout->Tab order and force it to be the fist one
Shay
|
|
|
|