|
That is a good idea. I'm not sure that I want to use it in this case though?
The function in the DLL is called many times and returns many character buffers. That means that I have to keep track of all of these allocated character buffers in the dll, so that wehn DestroyXXX is called I free them all. I also can't have a DestroyLastAllocatedBuffer() function that frees the most recently allocated character buffer because the function in the DLL can be called by many different threads. (caveat: you probably could do both of the above with some extra work, but it might be more work than it is worth?)
I'd prefer for the calling application to be able to call the DLL function to get a characted buffer and then free it right after it is done with the buffer.
I think I have another solution though. You can create a C++ object with a destructor that does the memory freeing. It seems to work, anyone see any problems?
// Text holder class
CTextHolder
{
public:
CTextHolder()
~CTextHolder() { delete text; };
char *text;
};
// This is the exported function in the dll
extern "C"
{
CTextHolder * getText()
{
CTextHolder *blah = new CTextHolder();
blah->text = new char[20];
return blah;
}
}
// This is the function in the application that calls the exported function in the DLL
void testCall(void)
{
HMODULE mod = LoadLibrary("d:\\plugin.dll");
if(mod == NULL)
return;
// Test function is typdefed as.. typedef CTextHolder * (*aFunc)(void);
testFunction getText = (testFunction) GetProcAddress(mod, "getText");
if(getText == NULL)
return;
CTextHolder *blah = getText();
// Yay.. this seems to work fine
delete blah;
FreeLibrary(mod);
}
|
|
|
|
|
You wouldn't need to keep a list of anything.
s = CreateXXX();
...
DestroyXXX( s );
The functions would be something like this:
char *CreateXXX()
{
return new char[20];
}
///
//I would actually Code CreateXXX as follows
//ERRCODE CreateXXX( char **s )
//{
// *s = new char[20];
// return NOERR;
///}
ERRCODE DestroyXXX( char *s )
{
delete s[];
}
|
|
|
|
|
That seemed like a good solution to me too and I tried it, but it gave me an access violation. There may have been some bugs in my code (not allocating a large enough buffer and overflowing it), I'll try it again.
Thanks!
|
|
|
|
|
I think thats called a destructor.
|
|
|
|
|
I agree,
The CreateXXX,DestroyXXX approach is a good approach *if* the DLL the is designed to
be used as a black box, where it is always responsible for allocation and deallocation
of resources. However the original poster did not specify that.
Sometimes the black box approach is not appropriate for architectural or performance
reasons. Other times it is. I think both approaches have their merits.
Stephen Kellett
|
|
|
|
|
I am trying to use RasDial to establish an internet connection, but am getting an error that I don't understand. Here is the code that I am using:
RASDIALPARAMS dialParams;
DWORD dwRes;
CString cs;
char szError[50];
dialParams.dwSize = sizeof( RASDIALPARAMS );
strcpy( dialParams.szEntryName, "" );
strcpy( dialParams.szPhoneNumber, "szPhone" );
strcpy( dialParams.szCallbackNumber, "" );
strcpy( dialParams.szUserName, "szUser" );
strcpy( dialParams.szPassword, "szPW" );
strcpy( dialParams.szDomain, "" );
dwRes = RasDial( NULL, NULL, &dialParams, 0, NULL, &m_hRasConn );
if( dwRes == 0 )
{
     m_list.AddString( "Success." );
}
else
{
     RasGetErrorString( dwRes, szError, sizeof(szError) );
     cs.Format( "Error: #%d = %s - Handle: %s", dwRes, szError, (m_hRasConn == NULL) ? "NULL" : "Non-NULL" );
     m_list.AddString( cs );
}
The error that I'm getting is that it "Cannot find phonebook entry." My understanding is that this makes no sense, since in Win98, phonebooks are not valid and should be ignored.
I've checked the article at http://www.codeproject.com/internet/dialup.asp, but my code seems identical to that example.
Does anyone have any suggestions?
Thanks,
Matt J
|
|
|
|
|
Hello, the codegurus around the world.;)
I think that you should put any name in szEntryName.
If you put szEntryName as "", it means no entry phonebook.
Have a nice day!
-Masaaki Onishi-
|
|
|
|
|
I'm developing some kind of editor that needs line numbers in this format "N%i" to work.
How should I get the key press and modify the text of the edit control?
Thank you in advance.
|
|
|
|
|
I'm trying to write an MDI multithreaded app. I know I'll have a socket thread and what I'm trying to do is create a thread for each document that is opened. These document threads will need to talk with the socket thread and also with the GUI (menu selections, tiling etc.) The problem I'm having right now is that if the user touches any of the menus or drags a document view around, the other document view aren't updated. This is why I started down the thread per document road. I have the docuement thread working in that I created a UI thread (AfxBeginThread(RUNTIME_CLASS(MyDocThreadClass), THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED);
The problem that I think I have is that I'm creating the document in the main thread using the doctemplate stuff then giving a pointer to the document to the thread that I create for that document. The DocThreadClass will handle and catch the messages for the document (to/from the socket) but I'd like to update the document view when these socket messages come in. I might be mistaken but I believe that I'll still have the problem of the GUI "locking" the doc threads whenever I try to update the view or whenever the main frame/thread interacts with the user (dragging, menu selections). I'm new to the whole MFC thing so II might be overlooking something simple. I'm also sorry about the length but I couldn't explain it very simply.
|
|
|
|
|
Hi,
I cant access Access 2000 file from VC 6 Enterprise Edition.
I tried opening the database and got the "Unrecognized database format <filename>". Earlier that file was created in Access 97 format (thru VC) and it was working fine. The problem is that I converted that file to Access 2000.
One thing is that Access 97 had Jet Version 3.0. And Access 2000 has version 3.5/4 (I got this info from registry).
Any one any ideas? Any update I have to install? If yes, plz give me the URL.
Thanks,
Ammar
|
|
|
|
|
Hello, the codegurus around the world.
Configuration of Access 2000 issue is known well as the bug at VC++.
You can find the solution in MSDN magazine or MSDN help, I think.
Some header file, which I forgot, configures which version of Access is used in VC++ project. So, we simply add the new lines to this header file for Access 2000.
Have a nice day!
-Masaaki Onishi-
|
|
|
|
|
Actually I do not think this is a bug, the problem comes from the fact that the Access 2000 uses new version of DAO (3.6) and MFC by default supports version 3.5. To correct this all you have to do is chage version of MFC that you are using. This can be done with following line of code, just make sure that you call this before you try to open the database:
AfxGetModuleState()->m_dwVersion = 0x0601;
Pz
|
|
|
|
|
Hi,
Many many thanks. I think your line of code works. Atleast it went thru that line in debug mode.
One more thing...
I am creating an access file in runtime with this code:
db.Create("DOB.mdb", dbLangGeneral, dbVersion30);
db.Execute("CREATE TABLE DOB (Name Text, Email Text)");
What happens is that this creates a file comaptible with Access97. Now I want to create a file for Access2000. dbVersion30 is for A97. I tried dbVersion35 and dbVersion40 but these two are undeclared identifier.
How to create Access2000 mdb file?
I have VC 6.0 Enterprise Ed.
Ammar
|
|
|
|
|
Thanks for the solution. It works fine.
However I couldnt find any info on AfxGetModuleState() in MSDN. Can you help me on this? Where to find info about this API and AFX_MODULE_STATE ?
Your email address will be appreciated.
Thanks,
Ammar
|
|
|
|
|
Are all the VCPP Common Controls Active X controls? For example CEdit.
|
|
|
|
|
No - they are classes derived from CWnd.
Christian
The content of this post is not necessarily the opinion of my yadda yadda yadda.
To understand recursion, we must first understand recursion.
|
|
|
|
|
Actually, CEdit is actually a Windows CONTROL which CEdit subclasses.
|
|
|
|
|
I'm a Windows programming beginner, been programming DOS for some time, starting to make the switch and I'm having a niggly bit of trouble trying to display a messagebox immediately after a dialog.DoModal() . Has anyone out there seen this type of behaviour where any messagebox call after a dialog box fails to be displayed? Did I miss something obvious?
The application was created as an simple MFC GUI app.
Your help is much appreciated.
//*********************************************************************
dlg.m_strWarningtext.Format(strMsgBuf);
nResponse = dlg.DoModal();
// >>>>> At this point, any messagebox call returns IDOK without even being displayed.
if (nResponse == IDOK)
{
// Do stuff
sprintf(strMsgBuf,"Messagebox text ");
nRetVal = MessageBox( NULL, (LPCTSTR)strMsgBuf, "Error", MB_OK | MB_ICONERROR );
// >>>>> nRetVal is always == IDOK and the messagebox won't display
}
else if (nResponse == IDCANCEL)
{
// Do stuff
}
//*********************************************************************
|
|
|
|
|
I don't know the answer, but if you're using MFC, replace the last two lines with
nRetVal = AfxMessageBox("MessageBox Test");
Christian
The content of this post is not necessarily the opinion of my yadda yadda yadda.
To understand recursion, we must first understand recursion.
|
|
|
|
|
Hello, the codegurus around the world.;)
If you use the debugger, you may find the reason.
I think that ::MessageBox() should be called in if (response == IDOK)
The other way is that we put MessageBox() in CMyDialog::OnOK().
We often tend to use MessageBox() to check something.
But, TRACE, TRACE1, and so on works also in the debug mode.
void CMyDialog::OnOK()
{
MessageBox("OK button works", "Test");
TRACE ("OK button works")
CDialog::OnOK();
}
Have a nice day!
-Masaaki Onishi-
|
|
|
|
|
Just spent 10 minutes putting together an eloquent version of this question together only for everything to screw up when I clicked the Submit button, so here is the short version.
Apologies for dumbness of question, 3 years as Consultant has left brain as mush and programming memory has faded. Decided to get back in to programming and am working through tutorials to get up to speed. Starting with do nothing dialog application that contains many of the Controls available so I have at least implemented each control and have an understanding of them.
Right now I am attempting to use the Picture Control and obviuosly am having some trouble or I wouldn't be here. MSDN CD's that shipped with Visual Studio 6 have shed no light and can't find any Code Project articles that answer my question. Picture control Properties tell me I can use Icon, Bitmap or Enhanced Metafile. If I add a control variable via ClassWizard it is CStatic, looking up it's Member Functions I find only functions for Bitmaps (just looked at Class Members and found the functions for Icons and Enhanced Metafiles).
This shortens and slightly changes the question. These functions are using HICON, HBITMAP etc. which means it isn't loading the separate files from disk but must have the files loaded via resources(???) prior to compiling.
Is this correct?
How do I load the relevant files?
If I'm not even close what should I do?
Michael Martin
Pegasystems Pty Ltd
Australia
martm@pegasystems.com
+61 413-004-018
|
|
|
|
|
You can use ::LoadImage to load an image from disk if it's a .bmp or .ico ( which is a bmp with a bit of extra info ).
If you have an image as a resource and are using MFC, you can do this
CBitmap bmp;
bmp.LoadImage(IDB_BITMAP);
a CBitmap will cast to HBITMAP, if not it has a m_hbitmap member variable and a GetSafeHandle() method ( which needs casting ).
You can also set the bitmap from resources in the dialog editor.
Christian
The content of this post is not necessarily the opinion of my yadda yadda yadda.
To understand recursion, we must first understand recursion.
|
|
|
|
|
I am using a CComboBox with some of Chris's mod's to make it so I can enter text
and have it populate the CEdit with the CComboBox content as I am typing.
(eg: Days of the Week, if I typed 'Mond' it would display the 'ay' as selected)
This is all good stuff - Thanks Chris.
However, I would like the DropDown to work at the same time. I added:
if (!this->GetDroppedState())
this->ShowDropDown();
to the OnEditUpdate method, but no matter which methods I try none seem to allow
the typing of text to "Highlight the selection of closest match".
I really don't want to implement my own dropdown window (as in the excellent
ComboTree example), so I was hoping there was some cool way to get the Handle to
the DropDown.
If you have any suggestions, or if you actually KNOW the solution (hope hope),
please post a reply.
many thanks
Julien.
|
|
|
|
|
to get the handle to the dropdown, why not try the ChildWindowFromPoint() function specifing a point just below the edit window?
I don't know, just a suggestion
---
Multitasking: Screwing up several things at once.
|
|
|
|
|
I've finished my ID3 tag editor ( I intend to ask permission from the person whose base code I used for the ID3 stuff and then submit it ), but I have one final problem. It compiles and runs in debug mode ( and works a treat, I've been using it ), but in release the linker complains that _main is not defined. The program was created with the appwizard for WTL that was in the OCt SDK, and the main dialog class is called CMain, so I don't know if it's getting confused, but I went through the settings looking for a discrepancy and could not find one. The debug build is 370 k, the release build ( after I put a dummy main() function in that just returns 0 ) is about 74.
The release build runs and gives me a dialog, but if I click a button or my listctrl, the whole thing crashes. Which is why I think the compiler is confused as to what constitutes my main dialog class.
If anyone has any suggestions, I sure would appreciate it...
Christian
The content of this post is not necessarily the opinion of my yadda yadda yadda.
To understand recursion, we must first understand recursion.
|
|
|
|