2

I am using Visual Studio 2010 with MFC and I am trying to make a rectangle that is red when a device is disconnected and green when it is. I have made the rectangle with the following code:

CRect lConnectStatus;
    GetDlgItem( IDC_CONNECT_STATUS ) -> GetClientRect( &lConnectStatus );
    GetDlgItem( IDC_CONNECT_STATUS ) -> ClientToScreen( &lConnectStatus );
    ScreenToClient( &lConnectStatus );
    mConnected.Create( GetSafeHwnd(), 10000 );
    mConnected.SetPosition( lConnectStatus.left, lConnectStatus.top, lConnectStatus.Width(), lConnectStatus.Height() );
    if( mDevice.IsConnected() ){
        mConnected.SetBackgroundColor(0, 255, 0);
    }
    else{mConnected.SetBackgroundColor(0, 0, 255);}

I inserted this snippet into the OnInitDlg method and the rectangle does appear, but it doesn't change to green when the device gets connected. Is there anyway I can refresh the window so that the code is executed again and the colour changes to green?

oodan123
  • 459
  • 2
  • 8
  • 23
  • Yes there is, look at [a `CWnd` reference](https://msdn.microsoft.com/en-us/library/1xb05f0h%28v=vs.100%29.aspx) and I'm sure you will find a way. – Some programmer dude Aug 04 '15 at 02:06
  • That link didn't overly help but thanks for commenting. – oodan123 Aug 04 '15 at 02:47
  • 1
    If you follow the link, there's another link to [the `CWnd` class members](https://msdn.microsoft.com/en-us/library/b5wzwdk7%28v=vs.100%29.aspx), which contains a section on [update and painting functions](https://msdn.microsoft.com/en-us/library/b5wzwdk7%28v=vs.100%29.aspx#_mfc_update.2f.painting_functions_cwnd) which lists, among others, the [`Invalidate`](https://msdn.microsoft.com/en-us/library/ax04k970(v=vs.100).aspx) and [`RedrawWindow`](https://msdn.microsoft.com/en-us/library/0fdz8ey6%28v=vs.100%29.aspx) functions. – Some programmer dude Aug 04 '15 at 02:53
  • Ah ok yeah I'm new to all this so I haven't got my head around the reference page yet. It looks like a good resource so ill keep it in mind for later on. Thanks – oodan123 Aug 04 '15 at 02:55

2 Answers2

5

What type of control is IDC_CONNECT_STATUS? If it is a static control you can eliminate all this code and handle WM_CTLCOLOR_STATIC in the parent dialog. Your message handler for that message will control the color of the static control. To refresh the static control call Invalidate on that control. That will cause it to call your WM_CTLCOLOR_STATIC message handler.

ScottMcP-MVP
  • 10,337
  • 2
  • 15
  • 15
  • Thank you good sir! I solved it slightly differently but your answer did help by getting me to use the `Invalidate()` function – oodan123 Aug 04 '15 at 02:32
2

Solved It, As I am new to C++ I didn't know that putting the code snippet into the OnInitDlg() method wouldn't work. So I put the code into the OnPaint()method and used the functions Invalidate() and UpdateWindow() to force the window to refresh when the device was connected/disconnected. Thanks for your help.

Edit Thanks to Barmak for suggesting not to create the control in the OnPaint() method. I have updated the code below.

program::OnInitDlg(){
    CRect lConnectStatus;
    GetDlgItem( IDC_CONNECT_STATUS ) -> GetClientRect( &lConnectStatus );
    GetDlgItem( IDC_CONNECT_STATUS ) -> ClientToScreen( &lConnectStatus );
    ScreenToClient( &lConnectStatus );
    mConnected.Create( GetSafeHwnd(), 10000 );
    mConnected.SetPosition( lConnectStatus.left, lConnectStatus.top, lConnectStatus.Width(), lConnectStatus.Height() );
}

program::OnPaint(){
    if( mDevice.IsConnected() ){
        mConnected.SetBackgroundColor(0, 255, 0);
    }
    else{mConnected.SetBackgroundColor(0, 0, 255);}
}

program::Connect(){
Invalidate();
UpdateWindow();
}

program::disconnect(){
Invalidate();
UpdateWindow();
}
oodan123
  • 459
  • 2
  • 8
  • 23
  • You haven't explained your code but it looks like you are creating a control inside `OnPaint` function. You are creating a control each time dialog is painted. The program will probably crash. – Barmak Shemirani Aug 04 '15 at 02:32
  • It doesn't crash, but I took your advice and created the control in the `OnInitDlg()` method and just put the if statement in the `OnPaint()` method. It still works correctly – oodan123 Aug 04 '15 at 02:41
  • Also try using `program::Connect() { mConnected.SetBackgroundColor(...); mConnected.Invalidate();}`, if it works then you won't need to override `OnPaint` – Barmak Shemirani Aug 04 '15 at 02:57
  • 1
    Why would you start with MFC if you're new to C++ ? You should get a look into Win32 and C++ in general first. – Blacktempel Aug 04 '15 at 05:17
  • I'm going to have to agree with @Blacktempel here. If you don't know C++ or the Windows API, you stand **zero** chance of ever understanding MFC. See [Prerequisites for learning MFC programming](http://stackoverflow.com/q/18165076/1889329) for more information. – IInspectable Aug 04 '15 at 06:52
  • I agree with you both, but I have been assigned a task to modify a program that uses MFC. Luckily I have sample code to point me in the right direction but I am learning as I go. – oodan123 Aug 04 '15 at 06:57