Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6942215
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 27, 20262026-05-27T12:59:09+00:00 2026-05-27T12:59:09+00:00

I am developing an application for Windows. I have written a class for drawing

  • 0

I am developing an application for Windows. I have written a class for drawing purposes, that will be accessed by several threads. The class is threadsafe by using mutex locks.

The good thing is, thread safety does not seem to be an issue, however, I seem to never get a lock when processing the WM_SIZE message (though I do get locks when processing other messages) and I do not understand why.

The class looks like this:

class DrawChildWindow {
    typedef boost::mutex::scoped_lock     scoped_lock;
    typedef boost::mutex::scoped_try_lock scoped_try_lock;
    typedef std::map<HWND, HDC>           WindowMap;
public:
    DrawChildWindow(HWND hWndParent);
    ~DrawChildWindow();

    // Will move the child window and repaint it
    void move(int x, int y, unsigned int cx, unsigned int cy);

    // Returns the HDC stored in the WindowMap
    HDC beginPaint();
    // Displays the edited HDC on the client area of the child window
    void endPaint();
private:
    static LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

    boost::mutex        m_mutexLocal;         // for work with member variables
    static boost::mutex s_mutexGlobal;        // for work with static variables

    static WindowMap    s_map;                // Manages the created child windows
    HWND                m_hWnd;               // Handle of the child window
};

I’ve shortened it to show only the methods and members that, in my opinion, might cause the trouble. This is the respective implementation:

DrawChildWindow::DrawChildWindow(HWND hWndParent) {
    // I've cut the once-only registration of the window class here
    scoped_lock lockG(s_mutexGlobal);
    scoped_lock lockL(s_mutexLocal);

    m_hWnd = CreateWindow(L"DrawChildWindow", NULL,
        WS_CHILDWINDOW | WS_DLGFRAME | WS_VISIBLE,
        0, 0, 0, 0,
        m_hWndParent, NULL, __DCW_HINST, NULL);
    s_map[m_hWnd] = NULL;
}

DrawChildWindow::~DrawChildWindow() {
    scoped_lock lockG(s_mutexGlobal);
    scoped_lock lockL(s_mutexLocal);

    WindowMap::iterator it = s_map.find(m_hWnd);
    if(it != s_map.end())
        s_map.erase(it);
    DestroyWindow();
}

void DrawChildWindow::move(int x, int y, unsigned int cx, unsigned int cy) {
    scoped_lock lockL(s_mutexLocal);

    MoveWindow(m_hWnd, x, y, cx, cy, TRUE);
}

HDC DrawChildWindow::beginPaint() {
    scoped_lock lockG(s_mutexGlobal);
    scoped_lock lockL(s_mutexLocal);

    WindowMap::iterator it = s_map.find(m_hWnd);
    if(it != s_map.end()) {
        if(!it->second) {
            // I create a compatible DC here
            // and fit it to match the client area size
        }
        // I clear the background of the DC here
        return it->second;
    }
    // This should never happen
    return NULL;
}

void DrawChildWindow::endPaint() {
    scoped_lock lockG(s_mutexGlobal);
    scoped_lock_lockL(m_mutexLocal);

    WindowMap::iterator it = s_map.find(m_hWnd);
    if(it != s_map.end()) {
        if(it->second) {
            // I BitBlt the HDC into the client area here
        }
    }
}

LRESULT CALLBACK DrawChildWindow::WndProc(HWND hWnd, UINT uiMessage, WPARAM wParam, LPARAM lParam) {
    switch(uiMessage) {
    case WM_SIZE:
        {   // This is the problematic block
            scoped_try_lock lockG(s_mutexGlobal);
            // This is never true
            if(lockG.try_lock()) {
                WindowMap::iterator it = s_map.find(hWnd);
                if(it != s_map.end() && it->second) {
                    DeleteDC(it->second);
                    it->second = NULL;
                }
            }
        }
        return 0;
    case WM_PAINT:
        {
            scoped_lock lockG(s_mutexGlobal);
            PAINTSTRUCT ps;
            HDC hDC = BeginPaint(hWnd, &ps);
            WindowMap::iterator it = s_map.find(hWnd);
            if(it != s_map.end() && it->second) {
                // I BitBlt it->second to hDC here
            }
            else {
                // Draw a notification that no data is available
            }
            EndPaint(hWnd, &ps);
        }
        return 0;
    }
    return DefWindowProc(hWnd, uiMessage, wParam, lParam);
}

boost::mutex               DrawChildWindow::s_mutexGlobal;
DrawChildWindow::WindowMap DrawChildWindow::s_map         = WindowMap();

I am aware of the fact that WM_SIZE will be called while CreateWindow() – so it will be called in my constructor, where s_mutexGlobal is indeed locked. This is why I implemented it as a scoped_try_lock.

When the parent window’s size is changed, I call move() to adjust the child window sizes, and they will be adjusted correctly, but the HDC of s_map will never be destroyed, and I fail to understand why I cannot lock s_mutexGlobal there.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-27T12:59:10+00:00Added an answer on May 27, 2026 at 12:59 pm

    The problem can be solved by using

    if(s_mutexGlobal.tryLock()) {
        WindowMap::iterator it = s_map.find(hWnd);
        if(it != s_map.end() && it->second) {
            DeleteDC(it->second);
            it->second = NULL;
        }
        s_mutexGlobal.unlock();
    }
    

    instead of the scoped_try_lock. I discovered this while experimenting, and would still appreciate if someone had an explanation for this behavior.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I'm currently developing a application where I will have multiple windows open using C#
I am developing an application that will have to run on both Windows and
i'm developing an application (wpf) that have 3 windows. in the main window user
I am developing a windows application using vb.net, I have a simple html page
I am developing a Windows application that will allow SharePoint administrators to copy a
Hai I am Developing an Windows application using C#.Net where I have to block
we're currently developing an application that makes extensive use of popup windows(*) and have
Hai every one I am developing an windows application in which i have to
I have been developing a C# windows form application in XP. It all works
Hi all i am developing a chat application ... i have multiple chat windows

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.