|
dmailman wrote: when clicked, sends a Unicode string (example “\u8000”) to the application (e.g. excel, word, notepad) that does has the focus.
By the time the button is clicked, your app (and not Excel, Word, etc.) has focus. I recommend caching the currently active (non-self) main window every few mSec and targeting it when the user presses the button.
/ravi
|
|
|
|
|
What about handling the WM_MOUSEACTIVATE in the button's parent window and returning
MA_NOACTIVATE (I haven't tried it)?
Mark
|
|
|
|
|
Many thanks for all the suggestions...they were very clever.
I ended up using the WS_EX_NOACTIVATE style in creating the window, and that worked just fine.
thanks again.
|
|
|
|
|
Hello,
If I am not mistaken the Spy++ should be available when I have my Visual C++ window up and running.
unfortunatly, I am unable to see this options. I believe I should have it under "TOOL" option, but when I check this menu option I cannot see it!!!
Could you help out regarding SPY++?
Thank you for your time,
Khoramdin
|
|
|
|
|
Is it not in your menu group for VC ?
Christian Graus - C++ MVP
'Why don't we jump on a fad that hasn't already been widely discredited ?' - Dilbert
|
|
|
|
|
Christian,
I don't have a Menu Group which contains only two items:
1- Visual Studio Tools
2- Microsoft Visual C++ 2005 Express Edition
Khoramdin
|
|
|
|
|
Oh, you have the express edition. That's probably the problem
Christian Graus - C++ MVP
'Why don't we jump on a fad that hasn't already been widely discredited ?' - Dilbert
|
|
|
|
|
Hello,
What edition do I have to have in order to get the Spy++?
Khoramdin
|
|
|
|
|
Khoramdin wrote: What edition do I have to have in order to get the Spy++?
Any of the non-Express editions.
"Approved Workmen Are Not Ashamed" - 2 Timothy 2:15
"Judge not by the eye but by the heart." - Native American Proverb
|
|
|
|
|
The app is called spyxx.exe
You may be right I may be crazy -- Billy Joel --
Within you lies the power for good, use it!!!
|
|
|
|
|
Howdy y'all,
I am using Visual C++ 6.0 MFC. I am writing my first multi-threaded application. The worker thread calls a function in another class that uses automation to create an excel spreadsheet. If I call this function from my primary thread everything works okay, but if I call it from my secondary thread the creation of the spreadsheet fails. Any information on what is happening here would be much appreciated.
Buck
|
|
|
|
|
BuckBrown wrote: the spreadsheet fails
Please provide detailed error information
led mike
|
|
|
|
|
If I call the function from the primary thread -
void CTests::OpenWorksheet()
{
COleVariant covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
// Start Excel and get the application object
if(!m_App.CreateDispatch("Excel.Application"))
{
AfxMessageBox("Couldn't start Excel and get application object.");
}
}
The call to m_App.CreateDispatch("Excel.Application")) begins to execute the following code -
BOOL COleDispatchDriver::CreateDispatch(LPCTSTR lpszProgID, COleException* pError)
{
ASSERT(m_lpDispatch == NULL);
// map prog id to CLSID
CLSID clsid;
SCODE sc = AfxGetClassIDFromString(lpszProgID, &clsid);
if (FAILED(sc))
{
if (pError != NULL)
pError->m_sc = sc;
return FALSE;
}
// create with CLSID
return CreateDispatch(clsid, pError);
}
As the function executes the values in my debug window are lpszProgID = 0x005902cc "Excel.Application", m_lpDispatch = 0x00000000, pError = 0x00000000 {COleException}, this = 0x00aa0158, &clsid = 0x0012ec4c {CLSID_Microsoft Office Excel Application}, sc = 0, and the CreateDispatch(clsid, pError) function returns a value of 1.
If I call m_App.CreateDispatch("Excel.Application") from the worker thread, the values are all the same but the call to CreateDispatch(clsid, pError) returns a value of 0.
If you want more detail, from the worker thread, the CreateDispatch(clsid, pError) function calls SCODE sc = CoCreateInstance(clsid, NULL, CLSCTX_ALL | CLSCTX_REMOTE_SERVER, IID_IUnknown, (LPLP)&lpUnknown); with values of CLSCTX_REMOTE_SERVER = 16, IID_IUnknown = {IID_IUnknown}, lpUnknown = 0x00000000, &lpUnknown = 0132fbbc. This call returns a value of -2147221008 into sc and then fails.
From the primary thread the value of lpUnknown is 0x0012ec28
From the secondary thread the value of lpUnknown is 0x0132fbbc
Other than this value everthing else is the same.
Thanks
|
|
|
|
|
BuckBrown wrote: This call returns a value of -2147221008 into sc and then fails.
Do you know that HRESULTS can be tested and represent specific errors?
Visual Studio 6 comes with a tool called "Error Lookup". Plug that number into it.
Here is a hint for you, COM must be initialized for each thread it is used in.
led mike
|
|
|
|
|
Thanks Mike,
No I didn't. First and foremost I am NOT a Windows programmer. I come from the UNIX world and everthing Microsoft seems back asswords to me. I have taught myself (with help from people like yourself) just enough MFC programming in the last couple of years to be dangerous, but it has been a real challenge because what experienced Windows programmers take for granted as kindergarten stuff is not really documented very well. I'll play with this angle for a while (it will probably take me a week) and let you know how it went.
Thanks again for getting me off the snide.
Buck
p.s. If you're wondering why a Windows hater is programming in it, it is because that was the compiler on my machine at work and it's the only one I have to develop applications with. I don't want to, I have to.
|
|
|
|
|
|
BuckBrown wrote: I am NOT a Windows programmer. I come from the UNIX world and everthing Microsoft seems back asswords to me. I have taught myself (with help from people like yourself) just enough MFC programming in the last couple of years to be dangerous, but it has been a real challenge because what experienced Windows programmers take for granted as kindergarten stuff is not really documented very well.
Ah, now that is useful information to aid in our communications! So the COM kernel of windows uses thread local storage for some of it's ?whatever? and therefore requires thread based intialization. Use the OleInitialize()[^] and matching uninitialize() to accomplish this in your thread callbacks when you want to use COM routines in a worker thread.
led mike
|
|
|
|
|
Hi,
Yes, not using the CoInitialize() function at the begining of the thread was the problem with not being able to create an Excel worksheet. Thank you all for your help. I didn't know anything at all about COM before, but now I guess I should bone up on it a little bit.
Buck
|
|
|
|
|
Did you initialize the apartment in the worker thread? You must ALWAYS call CoInitialize[Ex]() in a new thread before making ANY COM-calls...
Always take a look at the HRESULTs given by COM-functions. Then put the error code in the "Error Lookup"-tool that comes with Visual Studio (it's in the tools-menu). It can translate most common COM-errors.
Also, don't forget to call CoUninitialize() in your worker thread when it exits.
Good luck!
--
Verletzen zerfetzen zersetzen zerstören
Doch es darf nicht mir gehören
Ich muss zerstören
|
|
|
|
|
Hi,
Yes, not using the CoInitialize() function at the begining of the thread was the problem with not being able to create an Excel worksheet. Thank you all for your help. I didn't know anything at all about COM before, but now I gues I should bone up on it a little bit.
Buck
|
|
|
|
|
In addition to Joergen's reply, you have to marshal your interface into the new apartment.
Spawning a worker thread and not initializing COM by calling ::CoInitialize[Ex]() , is one of the top five mistakes when doing COM. Another one of the top five is using an interface gotten in the primary thread (apartment) without marshalling the interface. If you fail to do this you will get the RPC_E_WRONG_THREAD error.
Usually you marshal an interface by using ::CoMarshalThreadInterfaceInStream() and ::CoGetInterfaceAndReleaseStream() .
Have a look here[^].
I think that by about 95% certainty, the above is your problem.
"It's supposed to be hard, otherwise anybody could do it!" - selfquote
|
|
|
|
|
Hi,
Yes, not using the CoInitialize() function at the begining of the thread was the problem with not being able to create an Excel worksheet. Thank you all for your help. I didn't know anything at all about COM before, but now I gues I should bone up on it a little bit.
Buck
|
|
|
|
|
I've created 2 classes each with it's own dialog box in an MDI application
1. commanding class
2. picViewer class
the commanding class has a func load().
where i create a picViewer variable.
<br />
void commanding::load()<br />
{<br />
UpdateData (TRUE);<br />
<br />
FILE *pic, *pic1, *pic2;<br />
picViewer cam1; <br />
pic = fopen("C:\\cv\\16bit.jp2", "rb");<br />
pic1 = fopen("C:\\cv\\nature_50.jp2", "rb");<br />
pic2 = fopen("C:\\cv\\8_8.jp2", "rb");<br />
unsigned int numRead;<br />
<br />
int i = 0;<br />
while(i < 3)<br />
{<br />
if(i == 0)<br />
numRead = fread(buff, sizeof(BYTE), 100000, pic);<br />
else if(i == 1)<br />
numRead = fread(buff, sizeof(BYTE), 100000, pic1);<br />
else<br />
numRead = fread(buff, sizeof(BYTE), 100000, pic2);<br />
cam1.showPicture(buff,numRead);<br />
i++;<br />
Sleep(2000);<br />
}<br />
<br />
fclose(pic);<br />
fclose(pic1);<br />
fclose(pic2);<br />
UpdateData (FALSE);<br />
}<br />
<br /> the picViewer class has a func show().
<br />
void picViewer::show(BYTE bfr[], DWORD size)<br />
{<br />
HBITMAP m_bitmap = NULL;<br />
CImage image;<br />
CJpeg2kDecoder imDec;<br />
<br />
image = imDec.Open(bfr, size);<br />
m_bitmap = (HBITMAP)image;<br />
m_nCam1img.SetBitmap(m_bitmap); <br />
}<br />
whenever I run the application i open up both dialog boxes hit run on the commanding dialog box i get an error when i get to "m_nCam1img.SetBitmap(m_bitmap); " which points to:
<br />
_AFXWIN_INLINE HBITMAP CStatic::SetBitmap(HBITMAP hBitmap)<br />
{ ASSERT(::IsWindow(m_hWnd)); return (HBITMAP)::SendMessage(m_hWnd, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hBitmap); }<br />
in afxwin2.inl
what does that mean? what am i doing wrong? what would i need to do in order to show a picture in a separate dialog box?
thanks!
Kitty5
|
|
|
|
|
kitty5 wrote: picViewer cam1;
If picViewer is a window or dialog it is never being created therefore the CStatic child window is also never created so IsWindow(m_hWnd) returns false and Asserts during debugging.
led mike
|
|
|
|
|
led mike wrote: kitty5 wrote:
picViewer cam1;
If picViewer is a window or dialog it is never being created therefore the CStatic child window is also never created so IsWindow(m_hWnd) returns false and Asserts during debugging.
picViewer is the class that is related to the picViewer dialog.
I added both
<br />
cam1.Create(IDD_PICVIEWER,0); <br />
cam1.EnableWindow(TRUE);<br />
to my commanding::load() function.
this stops the crashing.
however, no picture is shown in the picViewer dialog box even though i call the show().
<br />
cam1.show(buff,numRead);<br />
Thanks!
-- modified at 14:35 Thursday 1st February, 2007
Kitty5
|
|
|
|