Drawing Doubt
-
Hi, I'm working on an application with many forms, i designed a layout for all the forms, but i wanted to build a class that had OnDraw(CDC* pDC) so i didn't have to override it from all my CFormView derived classes. I created a CLayout Class with OnDraw(CDC* pDC) function and now i would like to call it from other classes so i could draw and paint the forms. But, how can i get the pDC of this form? And i also need the hWnd pointer in my CLayout::OnDraw Function In my derived call i wrote: HWND* hWnd=NULL; hWnd=(HWND*)this->operator HWND(); CDC pDC=::GetDC(*hWnd); CLayout ly(hWnd); ly.OnDraw(&pDC); ...but GetDC function returns a HDC no CDC... This is my OnDraw Function... void CLayout::OnDraw(CDC* pDC) { //cria os objectos CBrush brush(RGB_FUNDO); CBrush* pTempBrush = NULL; CBrush OrigBrush; CString sFormName="New Machines"; CFont hFont; CRect rc; try { //cria a fonte para as letras de identificação do form VERIFY(hFont.CreateFont(40, 15, 0, 0, FW_NORMAL,FALSE, FALSE, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, "Arial Bold")); //define a area total do ecran GetClientRect(*hWnd,&rc); ScreenToClient(*hWnd,&rc); //seleciona o brush (cor) a usar pTempBrush = (CBrush*)pDC->SelectObject(brush); //guarda o brush original OrigBrush.FromHandle((HBRUSH)pTempBrush); //desenha o rectangulo a pintar com aquele brush pDC->Rectangle(0, 0, rc.Width() , rc.Height()); //defino a cor do texto pDC->SetTextColor(RGB_WHITE); //elimino o bkgrn do texto pDC->SetBkMode(TRANSPARENT); //associa-lhe a fonte criada pDC->SelectObject(hFont); pDC->DrawText(sFormName, -1, CRect(15, 0, rc.Width(),80), DT_LEFT|DT_SINGLELINE|DT_VCENTER); } catch(CResourceException* e) { e->ReportError(); e->Delete(); } pDC->SelectObject(&OrigBrush); } What am i doing wrong Thank you for your time rui
-
Hi, I'm working on an application with many forms, i designed a layout for all the forms, but i wanted to build a class that had OnDraw(CDC* pDC) so i didn't have to override it from all my CFormView derived classes. I created a CLayout Class with OnDraw(CDC* pDC) function and now i would like to call it from other classes so i could draw and paint the forms. But, how can i get the pDC of this form? And i also need the hWnd pointer in my CLayout::OnDraw Function In my derived call i wrote: HWND* hWnd=NULL; hWnd=(HWND*)this->operator HWND(); CDC pDC=::GetDC(*hWnd); CLayout ly(hWnd); ly.OnDraw(&pDC); ...but GetDC function returns a HDC no CDC... This is my OnDraw Function... void CLayout::OnDraw(CDC* pDC) { //cria os objectos CBrush brush(RGB_FUNDO); CBrush* pTempBrush = NULL; CBrush OrigBrush; CString sFormName="New Machines"; CFont hFont; CRect rc; try { //cria a fonte para as letras de identificação do form VERIFY(hFont.CreateFont(40, 15, 0, 0, FW_NORMAL,FALSE, FALSE, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, "Arial Bold")); //define a area total do ecran GetClientRect(*hWnd,&rc); ScreenToClient(*hWnd,&rc); //seleciona o brush (cor) a usar pTempBrush = (CBrush*)pDC->SelectObject(brush); //guarda o brush original OrigBrush.FromHandle((HBRUSH)pTempBrush); //desenha o rectangulo a pintar com aquele brush pDC->Rectangle(0, 0, rc.Width() , rc.Height()); //defino a cor do texto pDC->SetTextColor(RGB_WHITE); //elimino o bkgrn do texto pDC->SetBkMode(TRANSPARENT); //associa-lhe a fonte criada pDC->SelectObject(hFont); pDC->DrawText(sFormName, -1, CRect(15, 0, rc.Width(),80), DT_LEFT|DT_SINGLELINE|DT_VCENTER); } catch(CResourceException* e) { e->ReportError(); e->Delete(); } pDC->SelectObject(&OrigBrush); } What am i doing wrong Thank you for your time rui
You could try
CClientDC dc( this ); CLayout ly( *this ); ly.OnDraw( &dc );
but if this code gets called in OnPaint then you should use CPaintDC instead. You also might get away with supplying the hWnd of the form because CDC has a member function GetWindow( ) which returns the window associated with the device context (if there is a window BTW - returns NULL during printing for instance).
Wenn ist das Nunstück git und Slotermeyer? Ja! Beierhund das oder die Flipperwaldt gersput!
-
You could try
CClientDC dc( this ); CLayout ly( *this ); ly.OnDraw( &dc );
but if this code gets called in OnPaint then you should use CPaintDC instead. You also might get away with supplying the hWnd of the form because CDC has a member function GetWindow( ) which returns the window associated with the device context (if there is a window BTW - returns NULL during printing for instance).
Wenn ist das Nunstück git und Slotermeyer? Ja! Beierhund das oder die Flipperwaldt gersput!
Thank you dabs, I changed my code, now in my CFormView derived class OnInitialUpdate() i did like: ClientDC dc( this ); CWnd* cWnd=dc.GetWindow(); CLayout ly(cWnd ); ly.OnDraw( &dc ); then, i CLayout CRect rc; cWnd->GetClientRect(&rc); GetClientRect((HWND)cWnd, &rc); cWnd->ScreenToClient(&rc); but rc is like : tagRECT: {top=32730 bottom=32730 left=32768 right=32768} well, i forced other values, and it didn't draw the same, but in debug mode, i follow the pointer and it seems ok. What can i be doing wrong? Thanks once more for your time
-
Thank you dabs, I changed my code, now in my CFormView derived class OnInitialUpdate() i did like: ClientDC dc( this ); CWnd* cWnd=dc.GetWindow(); CLayout ly(cWnd ); ly.OnDraw( &dc ); then, i CLayout CRect rc; cWnd->GetClientRect(&rc); GetClientRect((HWND)cWnd, &rc); cWnd->ScreenToClient(&rc); but rc is like : tagRECT: {top=32730 bottom=32730 left=32768 right=32768} well, i forced other values, and it didn't draw the same, but in debug mode, i follow the pointer and it seems ok. What can i be doing wrong? Thanks once more for your time
Looks like you are using a CWnd* as a HWND. I recommend using Hungarian notation to be able to spot such problems - your variable would be called pWnd in that case. Secondly, you don't need that ScreenToClient call since GetClientRect uses client coordinates already. So change this code:
CRect rc; cWnd->GetClientRect(&rc); GetClientRect((HWND)cWnd, &rc); cWnd->ScreenToClient(&rc);
to this:CRect rc; cWnd->GetClientRect(&rc);
Wenn ist das Nunstück git und Slotermeyer? Ja! Beierhund das oder die Flipperwaldt gersput!
-
Looks like you are using a CWnd* as a HWND. I recommend using Hungarian notation to be able to spot such problems - your variable would be called pWnd in that case. Secondly, you don't need that ScreenToClient call since GetClientRect uses client coordinates already. So change this code:
CRect rc; cWnd->GetClientRect(&rc); GetClientRect((HWND)cWnd, &rc); cWnd->ScreenToClient(&rc);
to this:CRect rc; cWnd->GetClientRect(&rc);
Wenn ist das Nunstück git und Slotermeyer? Ja! Beierhund das oder die Flipperwaldt gersput!
Thank you dabs for the recommendation, I changed my code, it runs, in debug mode it passes without any problem by all code lines. Maybe the way i'm passing the pWnd pointer is incorrect, i'm doing like: CLayout::CLayout(CWnd* pWnd1) { pWnd=pWnd1; } pWnd is a member variable of CLayout My class is : class CLayout { public: CLayout(CWnd* pWnd1=NULL); ~CLayout(void); CWnd* pWnd; public: virtual void OnDraw(CDC* pDC); }; Should it be derived from CFormView also? I don't understand, it just don't draw, well, now rc is 0 for the four items...so it couldn't draw I'm suspicious about the pWnd that i pass from one class to another. What do you think? Thank you for your patience :)
-
Thank you dabs for the recommendation, I changed my code, it runs, in debug mode it passes without any problem by all code lines. Maybe the way i'm passing the pWnd pointer is incorrect, i'm doing like: CLayout::CLayout(CWnd* pWnd1) { pWnd=pWnd1; } pWnd is a member variable of CLayout My class is : class CLayout { public: CLayout(CWnd* pWnd1=NULL); ~CLayout(void); CWnd* pWnd; public: virtual void OnDraw(CDC* pDC); }; Should it be derived from CFormView also? I don't understand, it just don't draw, well, now rc is 0 for the four items...so it couldn't draw I'm suspicious about the pWnd that i pass from one class to another. What do you think? Thank you for your patience :)
The CWnd declaration and initialization is correct. And no, this class should not derive from CFormView unless you want to create another form :-) What happens in your Form's OnDraw and/or OnPaint functions?
Wenn ist das Nunstück git und Slotermeyer? Ja! Beierhund das oder die Flipperwaldt gersput!
-
The CWnd declaration and initialization is correct. And no, this class should not derive from CFormView unless you want to create another form :-) What happens in your Form's OnDraw and/or OnPaint functions?
Wenn ist das Nunstück git und Slotermeyer? Ja! Beierhund das oder die Flipperwaldt gersput!
Well, i'm just Using OnDraw() The function is : void CLayout::OnDraw(CDC* pDC) { //cria os objectos CBrush brush(RGB_FUNDO); CBrush* pTempBrush = NULL; CBrush OrigBrush; CString sFormName="New Machines"; CFont hFont; CRect rc; try { //cria a fonte para as letras de identificação do form VERIFY(hFont.CreateFont(40, 15, 0, 0, FW_NORMAL,FALSE, FALSE, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, "Arial Bold")); //define a area total do ecran pWnd->GetClientRect(&rc); //seleciona o brush (cor) a usar pTempBrush = (CBrush*)pDC->SelectObject(brush); //guarda o brush original OrigBrush.FromHandle((HBRUSH)pTempBrush); //desenha o rectangulo a pintar com aquele brush pDC->Rectangle(0, 0, rc.Width() , rc.Height()); //defino a cor do texto pDC->SetTextColor(RGB_WHITE); //elimino o bkgrn do texto pDC->SetBkMode(TRANSPARENT); //associa-lhe a fonte criada pDC->SelectObject(hFont); pDC->DrawText(sFormName, -1, CRect(15, 0, rc.Width(),80), DT_LEFT|DT_SINGLELINE|DT_VCENTER); } catch(CResourceException* e) { e->ReportError(); e->Delete(); } pDC->SelectObject(&OrigBrush); } I used this function in a OnDraw override from CFormView in my other class and i never thought it would be so dificult to make a class just for the propose... X| I would appreciate very much if you could still hepl me with this, thanks a lot :-D
-
Well, i'm just Using OnDraw() The function is : void CLayout::OnDraw(CDC* pDC) { //cria os objectos CBrush brush(RGB_FUNDO); CBrush* pTempBrush = NULL; CBrush OrigBrush; CString sFormName="New Machines"; CFont hFont; CRect rc; try { //cria a fonte para as letras de identificação do form VERIFY(hFont.CreateFont(40, 15, 0, 0, FW_NORMAL,FALSE, FALSE, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, "Arial Bold")); //define a area total do ecran pWnd->GetClientRect(&rc); //seleciona o brush (cor) a usar pTempBrush = (CBrush*)pDC->SelectObject(brush); //guarda o brush original OrigBrush.FromHandle((HBRUSH)pTempBrush); //desenha o rectangulo a pintar com aquele brush pDC->Rectangle(0, 0, rc.Width() , rc.Height()); //defino a cor do texto pDC->SetTextColor(RGB_WHITE); //elimino o bkgrn do texto pDC->SetBkMode(TRANSPARENT); //associa-lhe a fonte criada pDC->SelectObject(hFont); pDC->DrawText(sFormName, -1, CRect(15, 0, rc.Width(),80), DT_LEFT|DT_SINGLELINE|DT_VCENTER); } catch(CResourceException* e) { e->ReportError(); e->Delete(); } pDC->SelectObject(&OrigBrush); } I used this function in a OnDraw override from CFormView in my other class and i never thought it would be so dificult to make a class just for the propose... X| I would appreciate very much if you could still hepl me with this, thanks a lot :-D
Aside from the fact that you are casting a CBrush* to HBRUSH (which won't work) and that you forget to deselect your font out of the device context then there's nothing inherently wrong with this code. But why don't you simply use the resource editor in Visual C++ to arrange the form in a way you want? There are controls available that allow you to change the color of static text easily and if you want another background color in your form you can handle WM_ERASEBKGRND to change it. You actually don't need to do anything at all in OnDraw if you don't want to. Or are there other requirements that I'm not aware of?
Wenn ist das Nunstück git und Slotermeyer? Ja! Beierhund das oder die Flipperwaldt gersput!
-
Aside from the fact that you are casting a CBrush* to HBRUSH (which won't work) and that you forget to deselect your font out of the device context then there's nothing inherently wrong with this code. But why don't you simply use the resource editor in Visual C++ to arrange the form in a way you want? There are controls available that allow you to change the color of static text easily and if you want another background color in your form you can handle WM_ERASEBKGRND to change it. You actually don't need to do anything at all in OnDraw if you don't want to. Or are there other requirements that I'm not aware of?
Wenn ist das Nunstück git und Slotermeyer? Ja! Beierhund das oder die Flipperwaldt gersput!
I'm working with vc.nte, i don't know if it makes a diference... That cast is part of a piece of code i got and it worked, i hope that is not the reason this doesn't work. And, honestly, i don't know how to deselect my font out of the device context. The main reason i'm trying to do this is because the forms layout isn't completly defined, so if later i had to make changes in all, it would be easier, and if i could spare from creating more objects in my forms it would be better, but maybe that is what i'm going to do... Thank you a lot for your time and dedication ;) rui
-
I'm working with vc.nte, i don't know if it makes a diference... That cast is part of a piece of code i got and it worked, i hope that is not the reason this doesn't work. And, honestly, i don't know how to deselect my font out of the device context. The main reason i'm trying to do this is because the forms layout isn't completly defined, so if later i had to make changes in all, it would be easier, and if i could spare from creating more objects in my forms it would be better, but maybe that is what i'm going to do... Thank you a lot for your time and dedication ;) rui
Well you are correct - it shouldn't have to be that hard to display the form :-) And it does not have to be - as I said I think you would be better off by using the dialog editor in VC++. The brush handle vs pointer can easily be resolved though if you want to but since this code isn't working then there's not much point in it really... And to deselect the font you should use a similar technique as with the brush - i.e. save the old font and select it back when you are done with the one you are using.
Wenn ist das Nunstück git und Slotermeyer? Ja! Beierhund das oder die Flipperwaldt gersput!