|
This may be old news to everyone else, but I can't seem to compile anything with an STL header such as <vector> included without warnings. I've been asked to develop a project to compile with warnings set at level 4, but even a bare source file with a single line...
#include <vector>
...gives rise to 6 warnings.
Is there some way around this? Can I get better source code for the STL under Visual C++?
|
|
|
|
|
one line will fix it. put it before your STL includes.
#pragma warning(disable:4786)
-c
------------------------------
Smaller Animals Software, Inc.
http://www.smalleranimals.com
|
|
|
|
|
or....
#pragma warning(push, 3)
include all your STL headers here...
#pragma warning(push, 4)
- Anders
|
|
|
|
|
bonjour!
i've got a little worker thread in my CDocument derived class. i've also defined a message and a message handler in my CDocument. i tried to post my message with PostMessage(NULL,MYMESSAGE,...) but it didn't work. i think the decleration of MYMESSAGE is ok (#define UWM_MYMESSAGE (WM_APP + 7)
what's the right way to post messages to a cdocument?
thx benedikt
|
|
|
|
|
PostMessage sends the message to a window, and a worker thread doesn't have a window associated with it. Get a handle to your application's main window and use it, e.g.
HWND hMain = AfxGetMainWnd()->m_hWnd;
::PostMessage(hMain, MYMESSAGE, 0, 0);
|
|
|
|
|
thx for your reply. i tried it with the following statement but it does not work.
CWnd* m_pWnd = (CWnd*)AfxGetMainWnd();
CString* s = new CString(cstrName);
PostMessage((HWND)m_pWnd,UWM_PROGRESSDELETE,0,(LPARAM)s);
the afx_msg function is never called.
any ideas?
|
|
|
|
|
The AfxGetMainWnd() will return the main window of the thread that made the call and it's not likely to be to one you want it receive the message.
Furthermore, you should avoid using MFC objects in your thread if they have been created in another thread. MFC doesn't handle that very well...
My prefered solution is to pass the HWND you need to your thread as a parameter :
CWinThread* pThread = AfxBeginThread(MyThread, (HWND)m_hWnd); // or any HWND you want
UINT MyThread(LPVOID pParam)
{
HWND hWnd = (HWND)pParam;
::PostMessage(hWnd, ...
}
You can pass a CWnd* as well but remember you want be able to access all its methods. In your case, if you only want to do a pWnd->PostMessage(...), it will work.
-------------------------
Benoit Devigne
http://www.bdevigne.com
contact@bdevigne.com
|
|
|
|
|
Hi all:
Let two things sink in. (It took time for me to, anyways!)
(i) He just wants to access just the CDocument-derived object--not a window. CDocument is not derived from CWinThread. There can be command rounting via MFC, but NO message pump.
(ii) This is not a GUI thread, but a worker thread.
So, why bother with window handles and PostMessage API at all?
The solution is as simple as just passing the CMyDocument object as is!
CWinThread* pThread = ::AfxBeginThread( MyWorkerThreadProc, this );
In the worker thread proc
UINT MyWorkerThreadProc( void* pParam )
{
if( doc is no longer around )
{
return -1;
}
else
{
CMyDocument* pDoc = (CMyDocument*) pParam;
pDoc->CallAnyMemberFunction();
}
return 1;
}
Pl. correct me if I got something wrong. Thanks.
-- Ajit
Your project today is your great-grandchildrens' "ancestor clock."
|
|
|
|
|
thx for your answer. but it doesnt really work. CDocument don't have a HWND. here are all the relevant functions of my thread. maybe something other is wrong.
//the function which starts the thread
CUserManagerDoc::fnDeleteUser(CStringList &lstToDelete)
{
//is thread running?
if(bDeleteRunning)
{
MessageBox(NULL,"Es wird gerade gelöscht!","Achtung",MB_OK|MB_ICONEXCLAMATION);
return 1;
}
..... some code ....
bDeleteRunning = true;
pThread = AfxBeginThread(fnThreadDeleteUser,this);
return 1;
}
UINT CUserManagerDoc::fnThreadDeleteUser(LPVOID p)
{
//start the function
CUserManagerDoc* me = (CUserManagerDoc*)p;
me->fnThreadDeleteUser();
return 0;
}
//the thread function
void CUserManagerDoc::fnThreadDeleteUser()
{
..... some code ....
CString* s = new CString("Test");
CWnd* m_pWnd = (CWnd*)AfxGetMainWnd();
PostMessage((HWND)m_pWnd,UWM_PROGRESSDELETE,0,(LPARAM)s);
}
//message handler for the user defined message
LRESULT CUserManagerDoc::OnProgressDelete(WPARAM wParam, LPARAM lParam)
{
//get the text
CString *s = (CString *)lParam;
........ some code ......
return NULL;
}
|
|
|
|
|
OK. Got the picture almost fully.
Just one more part. Guess you have to look at how the message map entries for the UWM_PROGRESSDELETE look like in the project (not just in the Doc).
Since CDocument is not a CWnd (and also not a CWinThread), MFC will NOT find a way to directly route UWM_PROGRESSDELETE to CUserManagerDoc.
Therefore, you might have to add ON_THREAD_MESSAGE entries in CMyView or CMyFrameWnd where MFC will route these messages. Then, you could arrange for MFC to forward those to CDocument....
I would probably go for a more lengthy but a very straightforward and clean solution as following.
Derive a CMyWorkerThread from CWinThread class, and add ON_THREAD_MESSAGE entries for PROGRESSDELETE in CMyWorkerThread class, *not* in the CUserManagerDoc class.
Have a CMyWorkerThread* as m_pThread in Doc. Instantiate CMyWorkerThread on the heap in a doc function, and then call m_pThread->Create() to get the worker thread going. You can also cache the doc ptr as a member variable into the CMyWorkerThread class. If so, ensure you say
m_pThread->m_pCreatingDoc = this;
before calling m_pThread->Create().
To use: In CUserManagerDoc, call
m_pThread->PostThreadMessage( UWM_PROGRESSDELETE, 0, (LPARAM) pData );
To access Doc from CMyWorkerThread handler for ProgressDelete(), just use the cached ptr. (Some multi-threading synch object might be necessary to ensure m_pDoc in CMyWorkerThread is valid.)
This will always work. See if it is suitable for your needs.
-- Ajit
Your project today is your great-grandchildrens' "ancestor clock."
|
|
|
|
|
thanks for your detailed answer. i tried it with the first way you mentioned. I added the necessary message functions in my CMainFrame class. The message map handels the messages via ON_THREAD_MESSAGE(UWM_PROGRESSDELETE, OnProgressDelete) and ON_THREAD_MESSAGE(UWM_PROGRESSCREATE, OnProgressCreate). The CDocument function which stores the thread retrieves a window handle via m_pWnd = (HWND)AfxGetApp()->m_pMainWnd.
My thread function calls the function:
CString* s = new CString(cstrName);
PostMessage(m_pWnd,UWM_PROGRESSDELETE,0,(LPARAM)s);
but my message handlers are never called.
i think i don't really understand your second solution. creating the CMyWorkerThread is clear. caching the doc ptr too. but i'd like to send a message to something where i can savely make some changes on my user interface. i think you mentioned how to send messages into the running thread and not vice versa. or do i really understand nothing...
|
|
|
|
|
About the second solution I proposed (CWinThread derived class). Gee, you got it perfectly right--it will post messages to worker but not in reverse. Sorry.
So now I get the problem. (i)The worker thread should (ii) post (iii) user-defined messages to (iv) one of the main app windows. (v) But, even CMainFrame doesn't trap user messages (vi) via ON_THREAD_MESSAGE. This is getting interesting by itself because the mistake is going to be obviously small and simple... Lemme give it a try on a real program rather than just think about it and get back to you later if something strikes.
-- Ajit
Your project today is your great-grandchildrens' "ancestor clock."
|
|
|
|
|
Hi,
The first solution does work. Graft the following code on the AppWizard-generated MDI app (accept all defaults).
Notes:
1. ON_THREAD_MESSAGE must appear exactly once for each User-Message in the whole project.
2. Synch support (not shown) is necessary. The simpler check on window handle, ::IsWindow( hWndAcceptingPost ), does not work. It leads to mem leaks.
In App.h
#define MYMESSAGE (WM_USER+7)
In Doc.cpp
static UINT MyThreadProc( void* pParam );
UINT MyThreadProc( void* pParam )
{
HWND hWnd = (HWND) pParam;
int nIters = 10;
for( int i = 0; i < nIters; i++ )
{
::Sleep( 500 );
CString* pS = new CString;
pS->Format( "Done %d of %d", i, nIters );
::PostMessage( pH->m_hWnd, MYMESSAGE, (WPARAM)i, (LPARAM) pS );
}
return 0;
}
void CMyDoc::OnLaunchWorkerThread()
{
CWnd* pWnd = ::AfxGetMainWnd();
HWND hWnd = pWnd->GetSafeHwnd();
::AfxBeginThread( MyThreadProc, (void*) hWnd );
}
In MainFrame.h
protected:
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnMyMessage(WPARAM wParam, LPARAM lParam);
DECLARE_MESSAGE_MAP()
In MainFrame.cpp
BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd)
ON_WM_CREATE()
ON_THREAD_MESSAGE(MYMESSAGE, OnMyMessage)
END_MESSAGE_MAP()
void CMainFrame::OnMyMessage(WPARAM wParam, LPARAM lParam)
{
CString* pS = (CString*) lParam;
TRACE( "Got (%d) %s\n", (int)wParam, *pS );
delete pS;
pS = 0;
}
Your project today is your great-grandchildrens' "ancestor clock."
|
|
|
|
|
bonjour! thanks for your answer. now it works. i think there was a little problem with my PostMessage function. i used PostMessage(...) instead of ::PostMessage(...). PostMessage didn't work.
I wanted to access my CDocument. Now i've moved the code for my thread in a new class. This class gets a pointer to my CDocument. The thread now launches a dialog which shows a litte progress bar. this dialog is initialized with my CDocument pointer and receives the messages of my thread. I hope the Dialog can now savely access my Cdocument data.
bb benedikt
|
|
|
|
|
hey der,
Is the message handler working properly if you call it from the main thread?
If it is, then I would run the Spy tool to make sure that the message is being sent and then you can look at the parameters in the message to see that they are correct. Nothing but fun fun fun!;)
|
|
|
|
|
thx for your reply. the message handler works but the spy tool doesn't receive my message. (i think)
|
|
|
|
|
Hi all,
I have this problem:
I need to make a program that, when runned for the first time, creates a shortcut icon on the desktop and a group in Start menu.
How it is possible to do this ? What are the api to call??
Thanks all for any help...
Carlo Comino
|
|
|
|
|
You want to use the method: SHGetNewLinkInfo
BOOL SHGetNewLinkInfo(
LPCTSTR pszLinkTo,
LPCTSTR pszDir,
LPTSTR pszName,
BOOL *pfMustCopy,
UINT uFlags
);
Cheers,
-Erik
|
|
|
|
|
I need to have two binary dll's in my application as resources. I then will need to be able to copy them out to the hard drive and save them.
How do i get a handle to the resource (not using MFC is best) and what should i then do with it?
I'm doing this so i can include some of the MFC dll's in an setup application that are needed to run a different app.
This would really help me,
any code/suggestions Please
|
|
|
|
|
Does anybody know how to change the height of a combo-box? The "MeasureItem" function can only change the height of the items inside the combo.
thanks,
Bruno
|
|
|
|
|
please can you explain me what are threads and what are processes and
what is the difference between the two ?
thank you a lot
|
|
|
|
|
This won't be a very in depth answer, for more information check out "Advanced Windows" by Jeffrey Richter.
A process is an instance of a running program. You start a program, it will run in a seperate "process". A process must own at least one thread to execute the code in its process.
A thread runs within a process. A process can hold many threads, but it has to have at least one. A thread is what actually executes the code in a process.
I know this is very brief, but I hope it helps a little.
Wayne
|
|
|
|
|
thanks, it helped a lot ...
so process is running program
each thread have its own registers like ax,bx,CS:IP. Right ?
Use threads the same memory - memory of process ???
can one process access threads of another process?
one more question: is it ok to create around 20 threads/process - for example each thread for each wininet download ???
|
|
|
|
|
A good source would be Joseph M. Newcomer's articles on this site, under General Category Threads Processes & IPC.
Scott!
Put the big rocks in the glass jar first!
|
|
|
|
|
"... so process is running program each thread have its own registers like ax,bx,CS:IP. Right ?"
Not my expertise, but I think so, yes.
"Use threads the same memory - memory of process ???"
Same EXE image, yes. Global variables/objects is also shared between threads within a process. Locally defined variables/objects within a thread are not shared between threads.
"can one process access threads of another process?"
Don't think so.
"one more question: is it ok to create around 20 threads/process - for example each thread for each wininet download ???"
Yes, web servers usually contain many more threads than 20. Our company has software running 50+ threads also, a lot being threads with different tasks. Word uses a separate thread to print documents too, for example.
|
|
|
|