|
You did not mention when your DLL unloads but if the host process is exiting by way of the ExitProcess Function then the first thing that happens is termination of threads. ExitThread is never called, your thread is killed by the TerminateThread Function. Then your DLL is unloaded. At this point your thread is already dead. If you do not have any control ofer the source code/functionality of the host process then there is essentially nothing that you can do. Unless you hook the host process functions of course. Now that I think about it.. hooking FreeLibrary will get you nowhere. ExitProcess would perhaps be a better candidate.
Better yet, you could just design your DLL so it doesn't have to do all this crap when forcibly unloaded.
Best Wishes,
-David Delaune
|
|
|
|
|
Code-o-mat wrote: The problem is, by the time DLL_PROCESS_DETACH runs the thread has already been terminated
By what means has the thread been terminated already?
Why not make it so that DLL_PROCESS_DETACH posts the quit message to the window and then the thread cleans up and exits?
|
|
|
|
|
That's exactly what i did, but as said, when i get the DLL_PROCESS_DETACH the thread has already been killed. I think when the process calls FreeLibrary it automatically kills the threads created by the DLL and then calls the DLLMain function. So i guess it won't be possible to terminate the thread in DLLMain. I will have to find another way, thanks for the reply.
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
|
|
|
|
|
Just use an event object to synchronize.
1) Create an event object.
2) During Dll unload process, After posting the message to thread, wait for the event to be signaled.
3) When the thread finishes cleanup, it should signal the event and exit.
4) When the event is signaled, delete the event and just exit.
Does this helps?
Regards,
Jijo.
_____________________________________________________
http://weseetips.com[ ^] Visual C++ tips and tricks. Updated daily.
|
|
|
|
|
I simply use WaitForSingleObject with the handle of the thread after posting the message to wait for its termination. This worked fine in other cases, althorough i never before tried it in a DLL.
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
|
|
|
|
|
There is a variation of the GDI+ Graphics class method "MeasureString" that has an optional parameter "codepointsFitted" that is a pointer to an INT. The documentation states that it is supposed to receive the number of code points that were actually fit into the layout rectangle.
When I try to use this "codepointsFitted" parameter, the INT that is pointed to always has the character count of the input string regardless of whether it indicates that the text bounding rect is larger than the text layout rect.
Has anyone ever gotten this variation of "MeasureString" using the "codepointsFitted" parameter to work? If so, what is the trick to getting that parameter to populate with the correct value?
Status MeasureString(
const WCHAR *string,
INT length,
const Font *font,
const SizeF &layoutRectSize,
const StringFormat *stringFormat,
SizeF *size,
INT *codepointsFitted,
INT *linesFilled
) const;
|
|
|
|
|
Seems to be working fine for me. The layout rect you are passing probably has enough width + height to hold all of your characters. Keep in mind that MeasureString will utilize *all* available space including height. So when it runs out of width it continues to render the text onto the next line. Pass it a HUGE string with a BIG font and see if you get the same results.
My test code:
RectF rSize;
INT iFitted;
INT iLines;
StringFormat format;
format.SetAlignment(StringAlignmentNear);
Font fontBold(L"Arial", 32, FontStyleBold);
CRect rcWin;
GetWindowRect(&rcWin);
RectF rgd(rctWin.left,rctWin.top,rctWin.right,rctWin.top + 32);
graphics.MeasureString(L"Test-Test-Test",-1,&fontBold,rgd,&format,&rSize,&iFitted,&iLines);
I copied and pasted that "Test-Test-Test" string about 20 times back to back to make my string bigger. The function correctly returns how many characers it was able to fit into the rect.
Best Wishes,
-David Delaune
|
|
|
|
|
I thought I had tried everything. You reminded me that I needed one additional tweak to my format flag. I had "StringFormatFlagsNoClip" in there and it was apparently causing the issue.
Thanks for taking the time to help me out. It is greatly appreciated.
|
|
|
|
|
bob16972 wrote: Thanks for taking the time to help me out. It is greatly appreciated.
No problem, I just happened to be working in GDI+ when I came across your post.
Best Wishes,
-David Delaune
|
|
|
|
|
As every one in the whole world knows, each PC has a "media access card" which is uniqe uneversally. I'd like to identify each system through Its MAC Number. can any one help me please?
Thank you masters!
|
|
|
|
|
By using GetAdaptersInfo() function, you could get MAC address. Check here[^] for code snippet.
Regards,
Jijo.
_____________________________________________________
http://weseetips.com[ ^] Visual C++ tips and tricks. Updated daily.
|
|
|
|
|
Thank you. you're so kind.
|
|
|
|
|
Jusef Marzbany wrote: Thank you. you're so kind. Rose
_____________________________________________________
http://weseetips.com[ ^] Visual C++ tips and tricks. Updated daily.
|
|
|
|
|
Do you mean this: http://en.wikipedia.org/wiki/MAC_address[^]? If you do, a MAC address belongs to the network card in the computer (can also belong to a modem or other network-connected device), so if a computer has no network card it has no MAC address either, also if you change the network card (like, you buy a new one) you get a new MAC address, also these can be spoofed. Don't know if this applies to your case or not or if this is usefull information for you or not, but i thought i mention it, maybe it helps some way to clear up possible misunderstandings. Good luck with whatever you are doing.
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
|
|
|
|
|
Sometimes, I don't know how do I aprociate. You're so kind. thank you.
|
|
|
|
|
Hi
I have a CString variable in my class like bellow i want to initialize it to nothing which way is best
Here i listed two ways. If any way is best why?
class MyClass
{
CString name;
MyClass()
{
name = _T(""); //way 1
name.Empty(); //way 2
}
}
Thanks in advance
----------------------------
KRISHNA KUMAR T M
|
|
|
|
|
what about
MyClass() : name(_T(""))
{
}
|
|
|
|
|
As far as i know CString's default constructor initializes it to an empty string anyways, so you don't have to do that explicitly. Or am i wrong?
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
|
|
|
|
|
Code-o-mat wrote: CString's default constructor initializes it to an empty string anyways, so you don't have to do that explicitly.
Indeed!
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Hi
Can I write a windows service and create a UI thread in it which should be able to identify / receive windows messages and process them? Is a window / dialog needed for a UI thread so that it can handle windows messages?
Thanx
|
|
|
|
|
Well, window messages can only be sent to a window so you will actually need one to receive window messages. But you can run a message queue in a thread that has no windows in it and handle process/thread messages (which aren't directed towards any particular window).
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
|
|
|
|
|
You can associate a hidden window with a service.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<br />
Peter Weyzen<br />
Staff Engineer<br />
<a href="http://www.soonr.com">SoonR Inc -- PC Power delivered to your phone</a>
|
|
|
|
|
Hi
Is it possible to associate a hidden window with a service, moreover it is generally advised not to write interactive services (which have windows) and not use MFC support for windows services. So, how do I proceed?
Thanx
|
|
|
|
|
true... interactive services are become less viable in the newer versions of windows.
So, to have some sort of UI that controls your service, you'll could write a 2nd program which interacts with the service and serves as it's UI. You can use FindWindow to get the window to post messages to. There are other ways to communicate with a service that doesn't involve a window -- named pipes, tcp, mailslots, stuff like that.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<br />
Peter Weyzen<br />
Staff Engineer<br />
<a href="http://www.soonr.com">SoonR Inc -- PC Power delivered to your phone</a>
|
|
|
|
|
Hi, I have a application and I would like to command lien pass parameters to it. But in other exe this command line parameter is null.
STARTUPINFO SI;
PROCESS_INFORMATION PI;
SI.cb = sizeof(STARTUPINFOW);
SI.lpReserved = NULL;
SI.lpDesktop = NULL;
SI.lpTitle = NULL;
SI.dwX = CW_USEDEFAULT;
SI.dwY = CW_USEDEFAULT;
SI.dwXSize = CW_USEDEFAULT;
SI.dwYSize = CW_USEDEFAULT;
SI.dwXCountChars = 0;
SI.dwYCountChars = 0;
SI.dwFillAttribute = 0;
SI.dwFlags = STARTF_USESHOWWINDOW;
SI.wShowWindow = SW_SHOWNORMAL;
SI.cbReserved2 = 0;
SI.lpReserved2 = NULL;
SI.hStdInput = 0;
SI.hStdOutput = 0;
SI.hStdError = 0;
CString sCmdLin = " UserID";
BOOL bRet = CreateProcess( m_sProductPath+"\\B.exe",
sCmdLin,
NULL,
NULL,
FALSE,
0,
NULL,
NULL,
&SI,
&PI);
After changing sCmdLin parameter to sCmdLin = "UserID" OR sCmdLin = " /UserID". But still i m unable to get the command line parameter in process B.exe. Pls suggest.
Thanks
SNI
|
|
|
|