|
Thanks for your reply!
I have not tried, I will try it tomorrow when i come back to company.
But why use the micro ON_NOTIFY_EX_RANGE? MSDN says "Note that the ID of a tool tip is always 0" in
the article "Handling TTN_NEEDTEXT Notification for Tool Tips".
I set a breakpoint in my response function , when move cursor over the toolbar button,
my funtion can be entered. But the tooltip just can't be displayed.
|
|
|
|
|
gaspher wrote: I set a breakpoint in my response function , when move cursor over the toolbar button,
my funtion can be entered.
Then my suggestion will likely not help.
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"Man who follows car will be exhausted." - Confucius
|
|
|
|
|
I am trying to find an easier way to handle Abort mechanism for long running operations. I tried googling all CP articles but, still I can't find a better way to solve my problem. My application has huge code base. I have to carefully design the Abort functionality without making major changes to existing code. I want the future programmers to understand and debug the code easily. Adding more complexity, the application creates GUI / Glyphs on the fly.
Here are some solutions I found on CP:
1. Using PeekMessage loop and PumpMessage during long running operations. - Not feasible for huge apps, not easy to debug. Abort will be on and off.
2. Using worker thread for long operations, main thread becomes free, post completion status to main thread after completing long operation. - Gives most responsive app but, needs redesign of total code, exception handling will be difficult.
3. Using worker thread for creating glyphs, performing long operations and all from one single Worker Proc. - Not at all recommended. Window handles cannot be easily used from other threads without using CWnd::FromHandle() or Attach() methods. If there are any SendMessage() calls, it will lead to lead locks.
4. Using UIThread. - Will show an awkward Abort dialog every time but, solves problem very simply without having to change major code. There are other problems, The UIThread Abort dialog shows as seperate task bar button. This can be made as part of main app by making it tool window or by creating hidden window as parent. But, as the main window is busy, showing UIThread dialog when main thread is busy is something I need to solve.
I read one article: http://www.drdobbs.com/184416859[^] but can't understand the way to make it work. I request you people to take a look. In this, the author creates a new UIThread and the InitInstance waits until the long operation is done. I can't understand how this makes the main thread responsive. I tried it and it didn't work.
As you can understand, I am seeing all combinations. The Dr Dobbs article showed hope initially but did not work for me. Please guide me with your experience.
Thanks,
Murali Krishna.
|
|
|
|
|
I'd go for using the active object pattern [1] - that gives you parallism without bending your current code to much. "Just" make the classes with the long execution time methods active. It's similar to using worker threads but the implementation of those worker threads are (mostly) hidden within the classes so they appear like normal objects.
The bad news is that writing (or borrowing) the scaffolding to implement active objects can be a bit of a pain in the bum. However once you've done it it's fairly easy to make any class active by implementing a fairly thin proxy class to the app. Perhaps try it with a toy application and see if it's worth the pain?
Cheers,
Ash
[1] In brief the idea of the active object pattern is that every object has it's own worker thread. When method calls are made on the object the calls get queued and run whenever the worker thread is next idle. Return values are dished back to the calling function as futures - which look like normal variables but block when read until their completing worker thread signals them.
http://www.cs.wustl.edu/~schmidt/PDF/Act-Obj.pdf[^] describes the pattern but it may take several readings to avoid the "whoaaa, this is well over complicated!" feeling.
|
|
|
|
|
Ash,
Thanks for your quick reply. I am looking at the pdf and trying to understand. I think it will take a day or two.
BTW, I forgot to mention. My application uses CORBA synchronous RMI calls. I took a quick look of the pdf and saw some know issues.. didn't read completly.
Thanks,
Murali Krishna
|
|
|
|
|
My bad, I misread it. it is known uses. (not issues)
|
|
|
|
|
If you're using CORBA then using the active object pattern shouldn't be too hard a concept to grasp. You can think of a CORBA object as an active object running in another process/on another machine.
One option you might have might be to stick the long running stuff in their own processes and use CORBA, although you'll loose a bit (a lot?) of efficiency that way. It could save you the balls ache of implementing the active object pattern though and all the other problems you have with multiple threads although if you're using a lot of complex types in the interface marshalling might be hell.
Cheers,
Ash
|
|
|
|
|
Hi Ash,
I appreciate your interest in helping me. I am still finding a hard time to solve this. May be I am not smart enough to design this properly.
I went through the pattern. Even with this active object, if I have to make synchronous calls, the client must be blocked till the message is received. Or may take time some where in client also.
Consider this: (simplified for reading)
When I start an operation, My application performs following..
1. Connect to server (may take 2 secs)
2. Create a GUI for showing some data (milli secs)
2. Get data (RMI) (40 secs)
3. Update GUI (milli secs)
5. Based on the above data start creating next GUI.
6. Create next GUI.
6. Get modified data for second GUI. (RMI) (4 mins!)
7. Update second GUI
Till now these are sequential in my application. User can always create n number of GUIs. Each GUI creation and updation may require n RMI calls and they are synchrounous. Meaning, each RMI call is blocked till it is received and the marshalling args are huge. I may also get MBs of data.
Example: Consider following call stack.
DataIDL::GetData() // Use proxy to get data. Blocked till the data is fetched.
Glyph::GetData() // After glpyh creation
GlyphsHandler::Execute() // Creates Glyph get data and Update Glyph
Doc::Execute() // Execution start of all Glyphs
Doc starts Execution. Glyphshandler creates glyphs, gets data and updates glyph. It goes on for all glyphs. Now as it all sequential, I cannot decouple each IDL call to threads as the next call depends upon previous call's data.
Hope I am not taking too much of your time. Is it possible to asynchronously decouple the IDL getdata using active object so that the next call will have no effect?
Many thanks for your advices till now.
Murali Krishna
|
|
|
|
|
Not sure if this will be of help to you, but if you're using SendMessage from one thread to another, you can use the ReplyMessage API to achieve concurrency.
|
|
|
|
|
Hi all,
I have faced an amazing problem.
Please go through below steps to reproduce:
1. create two folders ex. new1 & new2 on D drive.
2. create one short cut of folder new1 like "Shortcut to new1" on D drive only.
3. Rename "Shortcut to new1" to "new2"
4. Execute below code
ShellExecute(GetSafeHwnd(), NULL, L"D:\\new2", L"", NULL,
SW_SHOWNORMAL);
Actual Results : It opens folder new1 from D drive.
Expected results : It should open folder new2 D drive.
|
|
|
|
|
Howdy.
It's a very simple fix. The outcome kinda makes sense too, to me.
Anyhoo, just try this instead -
ShellExecute(HWND_DESKTOP, NULL, L"C:\\new2\\", L"", NULL, SW_SHOWNORMAL);
|
|
|
|
|
|
you rename shortcut name , it dose not matter.
because if you change the shortcut name but it still target old one.
so you want to change target then you do
right click on shortcut --> select property -> change target path
|
|
|
|
|
Hi
I have a app which it build by VC++.When running it in my computer show message
This application has failed to start because the application configuration is incorrect. Reinstalling the application may fix this problem.
but run it other computer fine it.
My Computer have a C++ 2008 Redistributable.
Help me
|
|
|
|
|
reza toorani wrote: My Computer have a C++ 2008 Redistributable.
You need to install the redistributable package on the target computers too. You can download it from here[^]
|
|
|
|
|
I install redistributable package but give me error message
|
|
|
|
|
you have mixes version of the dlls. The installed dlls are others than the building dlls. Use the service pack level and/or check the manifest.
tip: dependency walker
Press F1 for help or google it.
Greetings from Germany
|
|
|
|
|
Thanks
I download Dependency Walker files and load .exe appliaction file.error MSVCR80D.DLL file.
I download this file and copy the root application.but give me error message.
|
|
|
|
|
Do you see the big fat "D" in the dll name. It is a debug build.
Press F1 for help or google it.
Greetings from Germany
|
|
|
|
|
the dll name is DT.dll
I think that "d" is for dll name.
If it is a debug build,What do I?
|
|
|
|
|
Ypu wrote "I download Dependency Walker files and load .exe appliaction file.error MSVCR80D.DLL file."
that means your app or some dlls is referring to a debug dll. You need a release build of that file.
Press F1 for help or google it.
Greetings from Germany
|
|
|
|
|
this application fine work in other computers.
|
|
|
|
|
If depends.exe says that your application links to MSVCR80D.DLL , it means that the application is a debug build.
Do you have Visual Studio 2005 installed on the computers where the application run properly, but not installed on the computer where it doesn't starts?
Remember that the debug versions of the C/C++ runtime libraries are provided with Visual Studio but they are not redistributable.
|
|
|
|
|
Hi sir,
I am trying to write a text into Bitmap,i am able to write.
But i am not able to fill the colur into the region where i am writing.
i.e the colour of bitmap and the text which i am writing is not matching.
Here is my code:
OnPaint()
{
CPaintDC dc(this);
CDC dcImage;
CRgn* rgn;
BITMAP bm;
if (!dcImage.CreateCompatibleDC(&dc))
return;
m_bitmap.GetBitmap(&bm);
CBitmap* pOldBitmap = dcImage.SelectObject(&m_bitmap);
CBrush mybrush(RGB(255,0,0));
dcImage.TextOut(521,95,"Testing");
rgn=new CRgn;
rgn->CreateFromPath(&dcImage);
dcImage.FillRgn(rgn,&mybrush);
dc.BitBlt(0, 0, bm.bmWidth, bm.bmHeight, &dcImage, 0, 0, SRCCOPY);
dcImage.SelectObject(pOldBitmap);
}
Any idea will be helpful
Thanks
Raj
|
|
|
|
|
From CRgn::CreateFromPath documentation [^]:
The device context identified by the pDC parameter must contain a closed path.
Please have a look at the following code sample [^].
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|