Window in a separate thread
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 13 of 13

Thread: Window in a separate thread

  1. #1
    Join Date
    Jan 2011
    Posts
    8

    Question Window in a separate thread

    Hi.

    I need to create a DLL which exports 2 functions:
    a) the function to create a new thread with window
    b) the function to terminate that thread (and we need to destroy it's window)

    with using WINAPI (MS VC++ 6).

    The reason of my issue that DLL should be attached to main application which can stay busy for a long time and this application are not responding to user's activity, but if there stays at least one active window, the user would not be confused.

    I'm not C programer, so please be patient.

    Here code that I wrote using google, msdn, etc. A problem that I can't create the window (the handle is NULL) so I need you mature advice. And 2nd question is what I need to terminate the child thread by calling function from the main thread (because of peeking windows messages I think I can't use semaphore... )?

    Code:
    #include "stdafx.h"
    #include "windowsx.h"
    
    HANDLE sem1;
    //-----------------------------------------------------------------------------------------------
    LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wparam,LPARAM lparam)
    {
    	if (Message == WM_DESTROY )
    	{
    		PostQuitMessage(0);
    		return 0;
    	}	
    	if (Message = WM_PAINT)
    	{		
    		HDC	hdc ( GetWindowDC(hwnd) );
    		CPen pen(PS_SOLID,4,RGB(255,0,0));
    		SelectObject(hdc,pen);
    		Ellipse(hdc,0,0,100,100);
    	}	
    	return DefWindowProc(hwnd,Message,wparam,lparam);
    }
    //-----------------------------------------------------------------------------------------------
    DWORD WINAPI doSometing(LPVOID p)
    {	
    	MSG  msg;
    	HWND hWnd;
    	HINSTANCE *hInst = (HINSTANCE*) p;
    
    	WNDCLASS w;
    	memset(&w,0,sizeof(WNDCLASS));
    	w.style = CS_HREDRAW | CS_VREDRAW;
    	w.lpfnWndProc = WndProc;
    	w.hInstance = *hInst;
    	w.hbrBackground = GetStockBrush(WHITE_BRUSH);
    	w.lpszClassName = "C Windows";
    	RegisterClass(&w);
    
    	hWnd = CreateWindow( "C Windows", "C Windows", WS_OVERLAPPEDWINDOW,
    		10,10,600,480,NULL,NULL,NULL,NULL);
    	
    	if (!hWnd) 
    		throw 1;
    
    	ShowWindow(hWnd,SW_SHOWNORMAL);
    	UpdateWindow(hWnd);	
    
    	while(GetMessage(&msg, hWnd, 0, 0))
    	{
    		TranslateMessage(&msg);
    		DispatchMessage(&msg);
    	}
    /*	while( dwWaitResult != WAIT_OBJECT_0 )
    	{
    		dwWaitResult = WaitForSingleObject( 
                sem1,   // handle to semaphore
                0L      // zero-second time-out interval
    		);
    		Sleep(1000);
    	}*/
    	return 0;
    }
    //--------------------------------------------------------------------------------------------------------
    extern "C" __declspec(dllexport) void StartInfoThread(HINSTANCE hInst)
    {
    	HANDLE	hThread1;
    	DWORD	dwGenericThread;
    	
    	sem1     = CreateSemaphore(NULL,1,1,NULL);
    	hThread1 = CreateThread(NULL,0,doSometing,&hInst,0,&dwGenericThread);	
    }
    extern "C" __declspec(dllexport) void  StopInfoTread(void)
    {
    	ReleaseSemaphore(sem1,   // handle to semaphore
                         1,      // increase count by one
                         NULL);  // not interested in previous count 
    }
    //--------------------------------------------------------------------------------------------------------
    
    BOOL APIENTRY _DllMain(HANDLE,DWORD,LPVOID)
    {
        return TRUE;
    }

  2. #2
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Wallisellen (ZH), Switzerland
    Posts
    17,301

    Re: Window in a separate thread

    It is a very bad idea to create a window in any secondary thread. Don't do it.
    Instead you should move all the things making your App busy from the main thread to a one or more worker threads.
    Victor Nijegorodov

  3. #3
    Join Date
    Jan 2011
    Posts
    8

    Re: Window in a separate thread

    Quote Originally Posted by VictorN View Post
    It is a very bad idea to create a window in any secondary thread. Don't do it.
    Instead you should move all the things making your App busy from the main thread to a one or more worker threads.
    Yes, I think so, but that application is Oracle Forms runtime, I can't modify it. Only available to change is my module which executes by this application :'(

  4. #4
    Join Date
    Jan 2011
    Posts
    8

    Re: Window in a separate thread

    Oh, I remember, there are exists some way to interact few applications between each others... it's pipes? so I can create independent application to read a pipe from main app. I think right?

  5. #5
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Wallisellen (ZH), Switzerland
    Posts
    17,301

    Re: Window in a separate thread

    Quote Originally Posted by DeadCat View Post
    Oh, I remember, there are exists some way to interact few applications between each others... it's pipes? so I can create independent application to read a pipe from main app. I think right?
    Yes, but you will have to modify this "application is Oracle Forms runtime" too.

    And there are many types of IPC: pipes, mailslots, sockets, clipboard, file mapping and so on...
    Victor Nijegorodov

  6. #6
    Join Date
    Jan 2011
    Posts
    8

    Re: Window in a separate thread

    Quote Originally Posted by VictorN View Post
    Yes, but you will have to modify this "application is Oracle Forms runtime" too.

    And there are many types of IPC: pipes, mailslots, sockets, clipboard, file mapping and so on...
    Why I can't do this from my DLL?

  7. #7
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    5,932

    Re: Window in a separate thread

    Well, as for me, there's nothing wrong in creating window in a secondary thread. Of course if you know what you do. And the problem with non-created window has nothing to do with the thread.
    Best regards,
    Igor

  8. #8
    Join Date
    Jan 2011
    Posts
    8

    Re: Window in a separate thread

    Igor, Victor, ok, I think it is not so important which way I select. But where in my code an error, why CreateWindow fails?

  9. #9
    Join Date
    Jan 2011
    Posts
    8

    Re: Window in a separate thread

    russian desc:
    Внешнее приложение запускает мой модуль (форма, написанная на специальном языке) и выполняет его. В моём модуле нет возможности влиять на обработку сообщений ОС, потому я не могу сделать так, чтобы окно приложения не зависало при длительных операциях, но я могу подключить к модулю любую динамическую библиотеку и вызвать функции из этой библиотеки.
    Если я сделаю принудительную отрисовку основного приложения из DLL, то всё равно сообщения WM_* ставятся в очередь и не будут обработаны пока программа выполняет вычисления.
    Хотелось бы, чтобы в DLL было две функции - создать окно в новом потоке, уничтожить поток (в теории, еще третья функция нужна для отображения в этом окошке статуса основного приложения).
    Проблема в том, что в моём коде где-то ошибки, т.к. окно не создаётся, то есть, в функции doSomething локальная переменная hWnd == NULL. В чём проблема? И ещё вопрос - как уничтожить потом второй поток из основного потока, ведь если поток будет зациклен на чтении оконных сообщений, то пока не придёт какое-нибудь сообщение в окно, поток не обновит информацию о семафоре или о другом событии.

  10. #10
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    5,932

    Re: Window in a separate thread

    Quote Originally Posted by DeadCat View Post
    Igor, Victor, ok, I think it is not so important which way I select. But where in my code an error, why CreateWindow fails?
    Funny thing, the main problem was in ... WM_PAINT handler. (Few other places as well.)

    Code:
    //#include "stdafx.h"
    #include <afxwin.h>
    #include "windowsx.h"
    
    HANDLE sem1;
    //-----------------------------------------------------------------------------------------------
    LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wparam,LPARAM lparam)
    {
        switch (Message)
        {
        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;
    
        case WM_PAINT:
            {
                PAINTSTRUCT ps = {0};
                HDC hdc = BeginPaint(hwnd, &ps);
                CPen pen(PS_SOLID,4,RGB(255,0,0));
                HGDIOBJ hPenOld = SelectObject(hdc,pen);
                Ellipse(hdc,0,0,100,100);
                SelectObject(hdc,hPenOld);
                CString txt = TEXT("Test");
                TextOut(hdc, 10, 10, txt, txt.GetLength());
                EndPaint(hwnd, &ps);
                return 0;
            }    
        }
    
        return DefWindowProc(hwnd,Message,wparam,lparam);
    }
    //-----------------------------------------------------------------------------------------------
    DWORD WINAPI doSometing(LPVOID p)
    {    
        DWORD err = 0;
        MSG  msg;
        HWND hWnd;
        HINSTANCE hInst = (HINSTANCE) p;
    
        WNDCLASS w;
        memset(&w,0,sizeof(WNDCLASS));
        w.style = CS_HREDRAW | CS_VREDRAW;
        w.lpfnWndProc = WndProc;
        w.hInstance = hInst;
        w.hbrBackground = GetStockBrush(WHITE_BRUSH);
        w.lpszClassName = TEXT("C Windows");
        RegisterClass(&w);
        err = GetLastError();
    
        hWnd = CreateWindow( TEXT("C Windows"), TEXT("C Windows"), WS_OVERLAPPEDWINDOW,
            10,10,600,480,NULL,NULL,NULL,NULL);
        
        if (!hWnd) 
        {
            err = GetLastError();
            throw 1;
        }
    
        ShowWindow(hWnd,SW_SHOWNORMAL);
        UpdateWindow(hWnd);    
    
        while(GetMessage(&msg, NULL, 0, 0))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    /*    while( dwWaitResult != WAIT_OBJECT_0 )
        {
            dwWaitResult = WaitForSingleObject( 
                sem1,   // handle to semaphore
                0L      // zero-second time-out interval
            );
            Sleep(1000);
        }*/
        return 0;
    }
    //--------------------------------------------------------------------------------------------------------
    extern "C" __declspec(dllexport) HANDLE StartInfoThread(HINSTANCE hInst)
    {
        HANDLE    hThread1 = NULL;
        DWORD    dwGenericThread;
        
        sem1     = CreateSemaphore(NULL,1,1,NULL);
        hThread1 = CreateThread(NULL,0,doSometing,hInst,0,&dwGenericThread);    
        return hThread1;
    }
    extern "C" __declspec(dllexport) void  StopInfoTread(void)
    {
        ReleaseSemaphore(sem1,   // handle to semaphore
                         1,      // increase count by one
                         NULL);  // not interested in previous count 
    }
    //--------------------------------------------------------------------------------------------------------
    
    BOOL APIENTRY _DllMain(HANDLE,DWORD,LPVOID)
    {
        return TRUE;
    }
    As I said, all works fine in a secondary thread. Compilable project attached.
    Attached Files Attached Files
    Best regards,
    Igor

  11. #11
    Join Date
    Jan 2011
    Posts
    8

    Thumbs up Re: Window in a separate thread

    Quote Originally Posted by Igor Vartanov View Post
    Funny thing, the main problem was in ... WM_PAINT handler. (Few other places as well.)

    As I said, all works fine in a secondary thread. Compilable project attached.
    Thank you, Igor, it works fine!

    Victor, thank you for advice too.

  12. #12
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    5,932

    Re: Window in a separate thread

    You're welcome.

    There is a thing I'd like to warn you about. Never do this again:
    Code:
    extern "C" __declspec(dllexport) void StartInfoThread(HINSTANCE hInst)
    {
    	HANDLE	hThread1;
    	DWORD	dwGenericThread;
    	
    	sem1     = CreateSemaphore(NULL,1,1,NULL);
    	hThread1 = CreateThread(NULL,0,doSometing,&hInst,0,&dwGenericThread);	
    }
    When you pass a pointer of a stack variable to another thread, the stack can be already destroyed to the moment when the thread tries to dereference the pointer. And garbage comes as the result.
    Best regards,
    Igor

  13. #13
    Join Date
    Jan 2011
    Posts
    8

    Re: Window in a separate thread

    Ok, I made this without any stack variables, thank you, Igor

    Here the final version:
    Attached Files Attached Files
    Last edited by DeadCat; January 21st, 2011 at 03:36 AM.

Posting Permissions

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


Azure Activities Information Page

Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This is a CodeGuru survey question.


Featured


HTML5 Development Center