|
The ultimate framework for thread programming is Douglas Schmidt's ACE library, which, among an impressive array of features, provides a thread pool.
Anyway, ACE can probably be an overkill if you're planning to do a simple program. Sherwood Hu's A programming model to use a thread pool could be a simpler alternative.
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
Hi guys,
I'm doing a ::PostMessage() to a window via a worker thread. The documentation for ::PostMessage() says that if the post succeeds, then the return value is nonzero. However, sometimes I get a zero result, and then I check the GetLastError() and this returns 0 as well (I'm assuming this means "no error", as the docs say nothing about this). I know the window handle I'm posting to is valid. What is going on?
Thanx
swinefeaster
Check out Aephid Photokeeper, the powerful digital
photo album solution at www.aephid.com.
|
|
|
|
|
Post some code here, then it's much easier to tell you whats wrong!
Or try ::SendMessage(..) instead
------------------------------
©0d3 ©®4©k3® - That's me!
------------------------------
|
|
|
|
|
Not much else to say but what I said in the previous post. I'm posting a custom message to a window that I know exists. Also, SendMessage() just won't do, as the message needs to be sent from a worker thread to the main gui thread.
cheers,
swinefeaster
Check out Aephid Photokeeper, the powerful digital
photo album solution at www.aephid.com.
|
|
|
|
|
Have you tried:
BOOL PostThreadMessage(
DWORD idThread, // thread identifier
UINT Msg, // message
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
);
------------------------------
©0d3 ©®4©k3® - That's me!
------------------------------
|
|
|
|
|
and try this to:
DWORD GetWindowThreadProcessId(
HWND hWnd, // [in] handle to window
LPDWORD lpdwProcessId // [out] process identifier
);
------------------------------
©0d3 ©®4©k3® - That's me!
------------------------------
|
|
|
|
|
Hmmm interesting . I didn't know about this api function. I'm going to try this.
Is there any easy way of getting the main ui thread? (instead of just retrieving it by the ui thread on startup and using ugly synchronization to get it in the worker thread)
What do I pass as the time? I'm assuming this is the value returned by GetTickCount(). The docs for MSG say nothing about the format of this field.
But shouldn't PostMessage() be thread safe anyways? It works for other messages... Oh btw the exact same code I mentioned in the original post does work sometimes.
Thanks!
swinefeaster
Check out Aephid Photokeeper, the powerful digital
photo album solution at www.aephid.com.
|
|
|
|
|
swinefeaster wrote:
What do I pass as the time? I'm assuming this is the value returned by GetTickCount(). The docs for MSG say nothing about the format of this field.
Pass where? :/
-------------------------------------------
And if you use the HWND that you created in the main thread you should get the main thread ID if you do lika this:
GetWindowThreadProcessId(hWnd, lpdwProcessId); // hWnd is the HWND that you created in the main thread. lpdwProcessId is the thread ID of the main process
After that do just:
PostThreadMessage(lpdwProcessId, WM_COMMAND, (WPARAM)ID_OK, 0); // Send a WM_COMMAND to the main thread.
I hope this work!!
------------------------------
©0d3 ©®4©k3® - That's me!
------------------------------
|
|
|
|
|
Oops I read the documentation wrong. I thought I was supposed to pass a MSG structure in the call to PostThreadMessage().
Anyways, I just tried using that call and I get the exact same result: PostThreadMessage() returns 0 and GetLastError() returns 0 as well.
What the hell is going on?
swinefeaster
Check out Aephid Photokeeper, the powerful digital
photo album solution at www.aephid.com.
|
|
|
|
|
GetLastError() Return values:
Code Description Name
-----------------------------------------------------------------------
0 The operation completed successfully. ERROR_SUCCESS
-----------------------------------------------------------------------
Well, as you see this is an return value from GetLastError that 0 is ERROR_SUCCESS and it means that there is no error... hm.. strange!
I don't remember, but did your message that you sent do any effect or so?
If not, there must be another error somewhere in the code or something... send me the code to my mail box or here if it's not so much! I'm sure I can give you more help if you do that!
------------------------------
©0d3 ©®4©k3® - That's me!
------------------------------
|
|
|
|
|
Just for laughs I'll post the code that did this:
bool posted = ::PostMessage(handle, message, wParam, lParam);
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
if(!posted)
{
DWORD error = GetLastError();
CWinApp* WinApp = AfxGetApp();
cSubMainApp* App = safe_dynamic_cast<csubmainapp*>(WinApp);
if(!App)
{
// Couldn't cast app.
ASSERT(false);
}
else
{
DWORD mainThreadId = App->GetMainUiThreadId();
posted = PostThreadMessage(mainThreadId, message, wParam,
lParam);
error = GetLastError();
}
}
Note that here I'm trying both api functions.
swinfeaster
Check out Aephid Photokeeper, the powerful digital
photo album solution at www.aephid.com.
|
|
|
|
|
swinefeaster wrote:
GetMainUiThreadId();
I don't recognize this method?
-----------------------------------------------
Tell me what message you're trying to send!
------------------------------
©0d3 ©®4©k3® - That's me!
------------------------------
|
|
|
|
|
Got your mail buddy!
------------------------------
©0d3 ©®4©k3® - That's me!
------------------------------
|
|
|
|
|
Do you know if the window actually receives the message?
|
|
|
|
|
He say that the code works sometimes... so it should! :/
------------------------------
©0d3 ©®4©k3® - That's me!
------------------------------
|
|
|
|
|
Two quick questions... [1] What is the *value* (WM_APP + 1, WM_USER + 1, etc.) of the message you are sending, and [2] what are you sending as the WPARAM and LPARAM parameters?
Peace!
-=- James.
|
|
|
|
|
Hey James,
Ok, so WM_USER is defined as:
#define WM_USER 0x0400
which is 1024 in decimal...
The id of the message I'm sending is 1385, so WM_USER + 361.
The WPARAM and LPARAM are both sent as 0, as I don't use them in this message.
Weird....
Cheers,
swinefeaster
Check out Aephid Photokeeper, the powerful digital
photo album solution at www.aephid.com.
|
|
|
|
|
Just want to post the code for the GetMainUiThreadId() function, as this was asked...
The GetMainUiThreadId() is simple... I basically have a cSubMainApp class
that adds some more functionality to CWinApp. This class has stores the
thread id on the thread that created it (which is always the main ui
thread). It does this with the following code:
m_mainUiThreadId = ::GetCurrentThreadId();
That variable is declared in the class as:
// The thread id of the main ui thread.
DWORD m_mainUiThreadId;
Also, the GetMainUiThreadId() is defined as:
DWORD
cSubMainApp::GetMainUiThreadId(void)const
{
return m_mainUiThreadId;
}
Nothing tricky to it, unfortunately. Any more ideas?
Thanks!
Check out Aephid Photokeeper, the powerful digital
photo album solution at www.aephid.com.
|
|
|
|
|
I want to add more than 256 controls onto a dialog,but after i added 255 controls,no more controls can be created.
Can anybody help me???Thanks a lot!
|
|
|
|
|
Add them with code
Nish
Sonork ID 100.9786 voidmain
www.busterboy.org
If you don't find me on CP, I'll be at Bob's HungOut
|
|
|
|
|
With that many controls on one dialog I would seriously consider redesigning my GUI.
|
|
|
|
|
i agree with mark
:wq
|
|
|
|
|
I need help obtaining a pointer to my CDocument class in a class that I have derived from CTabPageSSL. The TabPageSSL control can be found on this site and it essentially allows you to used child dialog box resources as a TabPage. My problem is this. I need to be able to take text entered on one tab and place it onto a diffent tab.
My view class is CFormView which I have then placed a tab control on the main view. On this control is where I have placed two tabs using the TabCtrlSSL. I can respond to the ON_EN_CHANGE of the individual tabs but I can not figure out how to pass this information on to the CDocument class. In all the examples that I have read and seen, they use a function called GetDocument() but this is only available inside my View class. I have attempted to create a function similar to it inside my derived class for my tab pages, but have had no luck.
Can anyone help me obtain a pointer to my CDocument or is there an easier way to pass information from between my child dialog boxes?
Thanks in advance for any help you can provide.
-Eric
|
|
|
|
|
you can use the following function to get your document from any place in your app (just replace 'CMyDocument')...
CMyDocument* DangerousGetDocument()
{
CWinApp* pApp = ::AfxGetApp();
POSITION p = pApp->GetFirstDocTemplatePosition();
ASSERT(p);
CDocTemplate* pTmp = pApp->GetNextDocTemplate(p);
p = pTmp->GetFirstDocPosition();
ASSERT(p);
CDocument* pDoc = pTmp->GetNextDoc(p);
ASSERT(pDoc);
return reinterpret_cast<CMyDocument*>(pDoc);
}
..have fun...
jk
|
|
|
|
|
jk,
Thanks for the help. I stumbled onto what appears to be an answer late last night. I am attempting the following...
CFrameWnd *pFrame = (CFrameWnd *)(AfxGetApp()->m_pMainWnd);
CFormView *pView = (CFormView *)pFrame->GetActiveView();
CMyDocument *pDoc = (CMyDocument *)pView->GetDocument();
Thanks again though for the help,
-Eric
|
|
|
|