|
I've got an ATL component that is used to get a Directory listing async for VB clients.
I have 3 interfaces in my Component.
IListing
IDirectory
IFileObject
I listing exposes a method of ExecuteImmediate, and Execute(it creates a thread to do the work).
It then uses the FindFirstFile/FindFirstFile etc to actually do the work.
In this area of the component, I create a CComObject<cdirectory> and store that in the member variable for my component.
Then the hard work is done, and each CComObject<fileobject> as added to the CDirectory object.
All this works perfectly. No leaks, etc.
I then call a property (Contents) to return the IDirectory which is my enumeration of the objects. Also fine.
If I add to the bottom of the ExecuteImmediate/Execute and Event to Fire_Complete(). The system crashes. I've gone through with the debugger, and I can't find anything.
I would really appreciate it if someone could identify any problems with this code(or if I should include some more).
<br />
<br />
DWORD WINAPI SearchFilesFunction2( LPVOID lpParam )<br />
{<br />
SearchFunction(lpParam);<br />
ExitThread(0);<br />
return 0;
<br />
}<br />
<br />
void SearchFunction( LPVOID lpParam )<br />
{<br />
USES_CONVERSION;<br />
CListing2* pListing;<br />
CComBSTR path;<br />
LPTSTR lpsz;<br />
BSTR directoryPath;<br />
BSTR directoryMask;<br />
bool Finished;<br />
<br />
WIN32_FIND_DATA FileFindData; <br />
HANDLE hSearch; <br />
<br />
pListing = (CListing2*)lpParam;<br />
<br />
pListing->m_inProgress = TRUE;<br />
<br />
lpsz = new TCHAR[512];<br />
pListing->get_Directory(&directoryPath);<br />
pListing->get_Mask(&directoryMask);<br />
<br />
path = directoryPath;<br />
path += directoryMask;<br />
<br />
hSearch = FindFirstFile(OLE2CT(path), &FileFindData); <br />
<br />
Finished = FALSE;<br />
<br />
if (hSearch == INVALID_HANDLE_VALUE) <br />
{ <br />
Finished= TRUE;<br />
} <br />
<br />
pListing->pDirectory = new CComObject<CDirectory>;<br />
<br />
while (!Finished) <br />
{ <br />
<br />
CComBSTR fullpath;<br />
BSTR bstr_Filename;<br />
<br />
CFileObject * pFileObject;<br />
pFileObject = new CComObject<CFileObject>;<br />
<br />
_tcscpy( lpsz, FileFindData.cFileName );<br />
<br />
bstr_Filename = SysAllocString(lpsz);<br />
<br />
fullpath = directoryPath;<br />
fullpath += bstr_Filename;<br />
<br />
pFileObject->put_Name(bstr_Filename);<br />
pFileObject->put_Path(directoryPath);<br />
<br />
if (FileFindData.dwFileAttributes & (FILE_ATTRIBUTE_DIRECTORY))<br />
{<br />
pFileObject->put_Type(1);<br />
fullpath += "\\";<br />
}<br />
else<br />
{<br />
pFileObject->put_Type(0);<br />
}<br />
<br />
pFileObject->put_Fullpath(fullpath);<br />
<br />
SysFreeString(bstr_Filename);<br />
<br />
pListing->pDirectory->Add(pFileObject);<br />
<br />
<br />
if (!FindNextFile(hSearch, &FileFindData)) <br />
{<br />
if (GetLastError() == ERROR_NO_MORE_FILES) <br />
{ <br />
Finished= TRUE;<br />
} <br />
else <br />
{ <br />
Finished= TRUE;<br />
} <br />
}<br />
}<br />
<br />
SysFreeString(directoryPath);<br />
SysFreeString(directoryMask);<br />
delete [] lpsz;<br />
<br />
FindClose(hSearch);<br />
pListing->m_inProgress = FALSE;<br />
pListing->Fire_Complete();<br />
}<br />
<br />
STDMETHODIMP CListing2::Execute()<br />
{<br />
<br />
m_inProgress = TRUE;<br />
<br />
hThread = CreateThread( <br />
NULL, <br />
0,<br />
SearchFilesFunction2,<br />
this, <br />
0,<br />
&dwThreadId);<br />
<br />
CloseHandle(hThread);<br />
return S_OK;<br />
}<br />
<br />
<br />
STDMETHODIMP CListing2::ExecuteImmediate()<br />
{<br />
m_inProgress = TRUE;<br />
SearchFunction(this);<br />
m_inProgress = FALSE;<br />
return S_OK;<br />
}<br />
<br />
STDMETHODIMP CListing2::get_Contents(IDirectory **pVal)<br />
{<br />
HRESULT hr;<br />
if (!m_inProgress)<br />
{<br />
<br />
hr = pDirectory->QueryInterface(IID_IDispatch, (void **)pVal); <br />
return S_OK;<br />
}<br />
else<br />
{<br />
return S_FALSE;<br />
}<br />
}<br />
<br />
<br />
|
|
|
|
|
Assuming you are not using free threaded apartments, you are in a canoe on a creek of manure, without paddles. You need to synchronize the apartments by marshalling the pListing interface pointer.
Take a look at Len Holgates excellent article which touches this subject: COM Mailslots - Designing asynchonous COM components for VB[^].
--
They're out get me, I can't escape cos' they won't let me
They won't forget me, they'll get me in their grip and sweat me
They'll wait me out, and then move in under my skin
They'll make me doubt, they're out to make me let them in
|
|
|
|
|
OK, Here is my message, I promise to make it quick!
I have downloaded the MultiThreaded server from http://www.codeproject.com/internet/winsockintro03.asp and I would like to know how I can replace "#Server Ready." with the persons IP.
Well, I added this code to the UINT ClientThread(LPVOID pParam):::
sockaddr_in from;
char temp[512];
sprintf(temp,"Your IP is %s\r\n",inet_ntoa(from.sin_addr));
send(client,temp,strlen(temp),0);
but it always replys back:
Your IP is 204.204.204.204
I use a loop back (127.0.0.1) so it should reply with this IP.
Have I done somethin rong?
If so pleaseeeee help me.
Thanks,
Tim
|
|
|
|
|
Hi Tim,
the reason that the ip address is always 204.204.204.204 is that 'from' hasn't been initialised.
you'll need to call getsockname to fill in the ip address.
ie:
<br />
sockaddr_in from;<br />
char temp[512];<br />
<br />
<br />
int fromlen;<br />
fromlen = sizeof(from);<br />
getsockname ( client, &from, &fromlen );<br />
<br />
sprintf(temp,"Your IP is %s\r\n",inet_ntoa(from.sin_addr));<br />
send(client,temp,strlen(temp),0);<br />
Hope this helps,
Andy Vincent
andyvinc at hotmail dot com
|
|
|
|
|
Could you tell me how to present Chinese character '人' using TCHAR? and what's the relationship between TCHAR presentation of a internation character and its Unicode 0x????format?
Regards
World on the way
|
|
|
|
|
TCHAR is a macro. If the UNICODE symbol is defined, TCHAR is defined as wchar_t , and as char otherwise.
Your Chinese character '人' is a double byte character, so it must be represented using wchar_t , as follows:
wchar_t chinese_character = L'人';
I cut/pasted your character into a file and looked at it using a hex editor. The character in hex is 0x4EBA.
Software Zen: delete this;
|
|
|
|
|
thanks for your explanation
Regards
World on the way
|
|
|
|
|
i want to make a program that runs at start up and keeps looking for, say MS word, n when its run it should add a menu in it
how???
|
|
|
|
|
One of the possible ways:
Using Spy find class of MS Word main window ("OpusApp"), and in your programm constantly check for new window of that class through EnumWindows and/or GetForegroundWindow and etc. As soon as new window of that class found -- you can modify it's menu...
"...Ability to type is not enough to become a Programmer. Unless you type in VB. But then again you have to type really fast..."
Me
|
|
|
|
|
I've got an edit box created with the ES_PASSWORD style and I need to toggle that based on a checkbox (similar to what WinZip does if you set a password on a zip file).
On XP it's behaving weird. GetPasswordChar returns 0x25CF, which is the Unicode code point for the default black dot (this is an ANSI app BTW). I can turn the password style off fine with SetPasswordChar(0) . But when I go to turn the style back on, I call SetPasswordChar(0x25CF) and it doesn't work, the edit box behaves as if I passed 0xCF instead, which gives Ï instead of the dot. Any ideas how to get this to work in an ANSI app?
--Mike--
Ericahist | CP SearchBar v2.0.2 | Homepage | RightClick-Encrypt | 1ClickPicGrabber
Pinky, are you pondering what I'm pondering?
I think so Brain, but if we shaved our heads, we'd look like weasels!
|
|
|
|
|
Michael Dunn wrote:
SetPasswordChar(0x25CF)
You might try using SendMessage(EM_SETPASSWORDCHAR,...) directly. It's possible the ANSI-ness of your application is confusing things in SetPasswordChar .
Software Zen: delete this;
|
|
|
|
|
|
Maybe you can just create 2 password input boxes: one with ES_PASSWORD style, another regular EDIT. You will show just one at a time.
BTW: RPlus ElSegundo desktop office is closing. Remember such? I am the only smoker there.
"...Ability to type is not enough to become a Programmer. Unless you type in VB. But then again you have to type really fast..."
Me
|
|
|
|
|
That's an interesting idea, I might try it There is a black dot character in Tahoma with value < 255 (I forget what the exact value is ATM) that looks almost, but not quite, like the default dot so I might just go with that.
Reuters eh? Sorry to hear that it's closing, but I had a miserable time there.
--Mike--
Ericahist [updated Oct 26] | CP SearchBar v2.0.2 | Homepage | RightClick-Encrypt | 1ClickPicGrabber
"That probably would've sounded more commanding if I wasn't wearing my yummy sushi pajamas."
-- Buffy
|
|
|
|
|
Hello, everyone!
Does anyone know how to kill a process by its process ID? Can anyone provide me some sample codes?
Thanks in advance,
Geo
|
|
|
|
|
|
Thanks, Michael buddy!
Geo
|
|
|
|
|
using TerminateProcess function
Best regards
Carlos Antollini.
Pi Five[^]Creator
|
|
|
|
|
Thanks, Carlos buddy!
Geo
|
|
|
|
|
If I add a text file as a resource, how can I write a new text file from that resource. Example... I have text files in my app, but I dont want to have to distribute the text files with it. I want to write temporary files and read from them, then delete them.
Thanks,
Daniel
|
|
|
|
|
I'm not sure I understand. You say that you do not want to distribute the text file.
Do you mean that you don't want to have separate files?
If so, then resources is the way to go!
How big are these text files?
Assuming that you have added the text files as resources to your app, you can simply call LoadResource() to get your text and from there create the temp files (if you actually need them).
Normally, there would be no reason to have a predetermined binary pattern (your text files) that would be written to disc and then read from. Why not just read the files' data directly from memory?
|
|
|
|
|
Well... What I have is a listbox. Each line in the file is a line in the listbox.
For my purposes, this is what I'm doing...
CStdioFile MyFile;
CListBox MyListbox;
MyFile.ReadSrting(String);
MyListBox::AddString(String);
Thats in a loop until EOF is reached. If I could do this directly from the resource, that would be great.
Thanks for the reply.
|
|
|
|
|
Daniel1324 wrote:
Each line in the file is a line in the listbox.
...
Thats in a loop until EOF is reached. If I could do this directly from the resource, that would be great.
Do you already know the value of the data? If not, resources probably aren't the answer.
|
|
|
|
|
I already know the valus... its all in a text file. Basically, what I want to do is read one line, and add that line to the listbox. Rightnow, i'm doing it by reading the text file. But, I want to add the text file into the resources so I wont have to distribute the text files with the app.
|
|
|
|
|
You can extract a resource to a file in this way:
bool ExtractResourceFile(const CString& resourceID, const CString& filename)
{
bool bOK = true;
HANDLE hRes = ::LoadResource(AfxGetResourceHandle(), ::FindResource(AfxGetResourceHandle(),
resourceID, "YOUR_RESOURCE_TYPE"));
if (hRes != INVALID_HANDLE_VALUE)
{
DWORD sizeOfResource = ::SizeofResource(AfxGetResourceHandle(),
::FindResource(AfxGetResourceHandle(), resourceID, "YOUR_RESOURCE_TYPE"));
char *lpRes = (char*)::LockResource(hRes);
CFile file;
if (file.Open(filename, CFile::modeCreate | CFile::modeWrite))
{
file.WriteHuge(lpRes, sizeOfResource);
file.Close();
}
else
{
bOK = false;
}
::UnlockResource(hRes);
::FreeResource(hRes);
}
return bOK;
}
Its up to you to delete the file once you have finished with it ::DeleteFile(filename)
Roger Allen
Sonork 100.10016
Death come early, death come late,
It takes us all, there is no reason.
For every purpose under heaven,
To each a turn, to each a season.
A time to weep and a time to sigh,
A time to laugh and a time to cry,
A time to be born and a time to die.
Dust to dust and ashes to ashes,
And so I end my song.
|
|
|
|
|