CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 30
  1. #1
    Join Date
    Apr 2008
    Posts
    93

    static drawing in Worker Thread

    i got this error when i try to run the pogram, how to solve the error?



    i have make the file to rar format so that is easy for access it.

  2. #2
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: static drawing in Worker Thread

    You are breaking the fundemental rule that says you can't access MFC UI components from a thread other than the thread that created the UI components.

    Usually you'll want to put all your UI components in the main UI thread, but if you absolutely can't live with this, check out the Multithreading: Creating User-Interface Threads article in Msdn.

  3. #3
    Join Date
    Apr 2008
    Posts
    93

    Re: static drawing in Worker Thread

    Quote Originally Posted by Arjay
    You are breaking the fundemental rule that says you can't access MFC UI components from a thread other than the thread that created the UI components.

    Usually you'll want to put all your UI components in the main UI thread, but if you absolutely can't live with this, check out the Multithreading: Creating User-Interface Threads article in Msdn.

    ??? basic user of visual c++, can explain in much simpler term?
    Last edited by ashwarrior; May 20th, 2008 at 12:43 AM.

  4. #4
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: static drawing in Worker Thread

    Quote Originally Posted by ashwarrior
    ??? basic user of visual c++, can explain in much simpler term?
    These MFC UI objects are created in the main UI thread:
    Code:
    	CDC		memdcDraw;
    	CBitmap bmDraw;
    but you are accessing them in your second thread:
    Code:
    // Secondary thread proc
    UINT CMy123Dlg::ABC(LPVOID pABC)
    {
    	CMy123Dlg*Draw=(CMy123Dlg*)pABC;
    	Draw->Test();
    	return 0;
    }
    
    void CMy123Dlg::Test()
    {
    	CBrush WhiteBrush(RGB(0,0,0));
    	memdcDraw.SelectObject(&WhiteBrush);
    	memdcDraw.SetBkMode(TRANSPARENT);
    	CPen WhitePen(PS_SOLID, 2, RGB(255,255,255));
    	memdcDraw.SelectObject(&WhitePen);
    
    	CFont myFont;
    	memdcDraw.SelectObject(&myFont);
    	memdcDraw.SetTextColor(RGB(255,255,255));
    
    	memdcDraw.Rectangle(50,50,100,100);
    	memdcDraw.TextOut(10,10,"hello");
    
        CClientDC dc(this);
    	dc.BitBlt(0,0,1100,800,&memdcDraw,0,0,SRCCOPY);
    }
    You aren't allowed to do that.

  5. #5
    Join Date
    Apr 2008
    Posts
    93

    Re: static drawing in Worker Thread

    oh i only have 1 thread, the function Test() is not a thread.

    UINT CMy123Dlg::ABC(LPVOID pABC)
    {
    CMy123Dlg*Draw=(CMy123Dlg*)pABC;
    Draw->Test();
    return 0;
    }

    this is the only thread i have inside the whole program.

  6. #6
    Join Date
    Apr 2008
    Posts
    93

    Re: static drawing in Worker Thread

    // Secondary thread proc
    UINT CMy123Dlg::ABC(LPVOID pABC)
    {
    CMy123Dlg*Draw=(CMy123Dlg*)pABC;
    Draw->Test();
    return 0;
    }

    void CMy123Dlg::Test()
    {

    }

    when i build the program with this code i got no errors and can run.
    so maybe is the the static drawing statement causing all the problem?.

  7. #7
    Join Date
    Apr 2008
    Posts
    93

    Re: static drawing in Worker Thread

    Quote Originally Posted by Arjay
    You are breaking the fundemental rule that says you can't access MFC UI components from a thread other than the thread that created the UI components.

    Usually you'll want to put all your UI components in the main UI thread, but if you absolutely can't live with this, check out the Multithreading: Creating User-Interface Threads article in Msdn.

    btw im using Worker thread instead of User interface thread

  8. #8
    Join Date
    Aug 2002
    Location
    Cluj-Napoca,Romania
    Posts
    3,496

    Re: static drawing in Worker Thread

    Quote Originally Posted by ashwarrior
    oh i only have 1 thread, the function Test() is not a thread.

    UINT CMy123Dlg::ABC(LPVOID pABC)
    {
    CMy123Dlg*Draw=(CMy123Dlg*)pABC;
    Draw->Test();
    return 0;
    }

    this is the only thread i have inside the whole program.
    No, there are 2 threads: the main UI thread and the worker thread serviced by the UINT CMy123Dlg::ABC(LPVOID pABC) function. As previously stated you cannot do this. Your worker thread should send requests ( messages) to the main thread to perform any UI operations.
    Har Har

  9. #9
    Join Date
    Apr 2008
    Posts
    93

    Re: static drawing in Worker Thread

    Quote Originally Posted by PadexArt
    No, there are 2 threads: the main UI thread and the worker thread serviced by the UINT CMy123Dlg::ABC(LPVOID pABC) function. As previously stated you cannot do this. Your worker thread should send requests ( messages) to the main thread to perform any UI operations.
    so i should put the declaring of memdc statement inside the worker thread instead of the main UI Thread?

    and the worker thread is UINT CMy123Dlg::ABC(LPVOID pABC) then which is the main UI thread? is it CMy123Dlg()?

  10. #10
    Join Date
    Aug 2002
    Location
    Cluj-Napoca,Romania
    Posts
    3,496

    Re: static drawing in Worker Thread

    Quote Originally Posted by ashwarrior
    so i should put the declaring of memdc statement inside the worker thread instead of the main UI Thread?
    Well, currently that function is called from within your worker thread hence all the problems. Your worker thread should only send a message to the main UI thread requesting itself to draw what is needed.

    [QUOTE=ashwarrior]
    and the worker thread is UINT CMy123Dlg::ABC(LPVOID pABC) then which is the main UI thread? is it CMy123Dlg()?[/code]
    Not quite. The main thread is the one in which all your application's code is executed by default, including CMy123Dlg. That thread is hidden by MFC but if you look at your application's class you will see it is derived at some point from CWinThread.
    Har Har

  11. #11
    Join Date
    Apr 2008
    Posts
    93

    Re: static drawing in Worker Thread

    Quote Originally Posted by PadexArt
    Well, currently that function is called from within your worker thread hence all the problems. Your worker thread should only send a message to the main UI thread requesting itself to draw what is needed.
    let me rephrase it, so the main UI thread do all the drawing and just have the worker thread to do the message?

    the message you mention is it AfxBeginThread()?


    Quote Originally Posted by PadexArt
    Not quite. The main thread is the one in which all your application's code is executed by default, including CMy123Dlg. That thread is hidden by MFC but if you look at your application's class you will see it is derived at some point from CWinThread.
    so i need CWinThread as my main UI Thread?

  12. #12
    Join Date
    Aug 2002
    Location
    Cluj-Napoca,Romania
    Posts
    3,496

    Re: static drawing in Worker Thread

    et me rephrase it, so the main UI thread do all the drawing and just have the worker thread to do the message?
    yes

    the message you mention is it AfxBeginThread()?
    No, that is the function you use to start the thread. You need to:
    - define a custom message ( user defined message)
    - send that message from the worker thread when drawing is required. Use PostMessage/PostThreadMessage
    - handle the message in the UI thread to do the actual drawing

    You can define a message using a constant like WM_USER + 100 or you can use RegisterWindowMessage

    so i need CWinThread as my main UI Thread?
    You already have it. It gets constructed by the framework ( MFC).
    Har Har

  13. #13
    Join Date
    Apr 2008
    Posts
    93

    Re: static drawing in Worker Thread

    Quote Originally Posted by PadexArt
    That thread is hidden by MFC but if you look at your application's class you will see it is derived at some point from CWinThread.
    i cant see that CWinThread at the Class.

    Quote Originally Posted by PadexArt
    No, that is the function you use to start the thread. You need to:
    - define a custom message ( user defined message)
    - send that message from the worker thread when drawing is required. Use PostMessage/PostThreadMessage
    - handle the message in the UI thread to do the actual drawing
    this part i only can understand abit. i still confuse about the message in the UI Thread to do the drawing.

  14. #14
    Join Date
    Apr 2008
    Posts
    93

    Re: static drawing in Worker Thread

    i got another question.

    previously Arjay say that my MFC UI objects are created in the main UI thread and i access them in the second thread which is wrong.

    where should the static drawing statment should i put at?

    I know its belong in the UI thread but where is the UI Thread? i cant located CWinThread.

  15. #15
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: static drawing in Worker Thread

    When any application starts up the system creates at least one thread (of execution) called the primary thread. From that point on, it is up to the individual application to create additional threads.

    An MFC application is no different whether it's a dialog, SDI, or MDI based application.

    The starting point of the MFC app is it's WinApp derived class, when the application starts up and this class gets created it gets created in the application's primary thread. Typically an MFC app will have some UI portion and that to will get created in the primary thread (again whether it's a dialog, SDI or MDI app). Once this UI is created, a message pump gets added to the primary thread, which essentially turns it into a UI thread.

    The heirarchy for these application types in terms of the UI are:

    Code:
    Dialog app
    CMyApp (CWinApp derived)
     L CMyDialog (CDialog derived)
    Code:
    SDI
     L CMyApp (CWinApp derived)
      L CMainFrame (CFrameWnd derived)
        L CMyView (CView derived)
    Code:
    MDI
     L CMyApp (CWinApp derived)
      L CMainFrame (CFrameWnd derived)
       L CChildFrame (CMDIFrameWnd derived)
        L CMyView (CView derived)
    It is important to understand that all of these classes and windows run in the primary or UI thread of the application.

    Ashwarrior, this should answer your question about not being able to find the UI thread.

    As far as send a message to draw....

    What you do is create a user defined message (i.e. WM_USER + 1), create a Message handler in your view (or dialog) that contains the drawing code. Keep in mind that this message handler, being in the view class, runs in the main thread.

    From your non-UI, worker thread send the user defined message to the view (when you create the worker thread, you pass in an hwnd of window you wish to send messages to).

    If you understand this much, then let us know and we can tell you how to pass data between threads in a thread safe manner.

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured