|
When I've had to use really old versions of something... I've gone to ebay and looked there. The other way would be if you have an MSDN subscription, since MS usually makes all versions of their IDEs available to developers to download through there, but a subscription is pricey to begin with (you'll likely find it cheaper through some third party online).
|
|
|
|
|
In OnTimer, I write a test program. if I don't use CreateCompatibleDC(), It works well, otherwise, no display.
Please help me to find the reason.
void CDynamicShowTextDlg::OnTimer(UINT nIDEvent)
{
CDC *pDC;
CRect tRect;
CDC MemDC;
pDC = this->GetDC();
GetClientRect(&tRect);
MemDC.CreateCompatibleDC(NULL);
MemDC.SetBkMode(TRANSPARENT);
if (test == 0 ){
MemDC.SetTextColor(RGB(255,255,255));
MemDC.DrawText(_T("My Test"),&tRect,DT_CENTER|DT_VCENTER|DT_SINGLELINE);
MemDC.SetTextColor(RGB(255,0,0));
MemDC.DrawText(_T("TEST"),&tRect,DT_CENTER|DT_VCENTER|DT_SINGLELINE);
}
else {
MemDC.SetTextColor(RGB(255,255,255));
MemDC.DrawText(_T("TEST"),&tRect,DT_CENTER|DT_VCENTER|DT_SINGLELINE);
MemDC.SetTextColor(RGB(0,150,0));
MemDC.DrawText(_T("My Test"),&tRect,DT_CENTER|DT_VCENTER|DT_SINGLELINE);
}
m_Seconds++;
m_TimerEcho.Format(_T("%d: Seconds have passed"), m_Seconds);
test ^= 1;
MemDC.DeleteDC();
ReleaseDC(pDC);
UpdateData(FALSE);
}
with pDC, it works well.
modified 17-Mar-14 11:40am.
|
|
|
|
|
You can see drawing operations occurred into a memory device context only if you BitBlt it to a 'standard' device context (see, for instance "CDC::CreateCompatibleDC" at MSDN[^].
Veni, vidi, vici.
|
|
|
|
|
I added a statement:
int nX = tRect.left + tRect.Width() / 2;
int nY = tRect.top + tRect.Height() / 2;
pDC->BitBlt(nX, nY, tRect.Width()/3, tRect.Height()/3, &MemDC,
0, 0, SRCCOPY);
But still get nothing on the screen.
|
|
|
|
|
you need to create a bitmap for your memdc to draw on.
see MSDN dox for CDC::CreateCompatibleDC:
http://msdn.microsoft.com/en-us/library/kwxzck32.aspx[^]
from the dox:
When a memory device context is created, GDI automatically selects a 1-by-1 monochrome stock bitmap for it. GDI output functions can be used with a memory device context only if a bitmap has been created and selected into that context.
|
|
|
|
|
Thanks, now the test string appeared.
But, the client area is black, and show text string in while color only, no change.
Please refer to the code:
void CDrawTextTstDlg::OnTimer(UINT_PTR nIDEvent)
{
CDC *pDC;
CRect tRect;
CDC MemDC;
pDC = this->GetDC();
GetClientRect(&tRect);
MemDC.CreateCompatibleDC(NULL);
CBitmap bmp;
bmp.CreateCompatibleBitmap(&MemDC, tRect.Width(), tRect.Height());
CBitmap *oldBitmap = MemDC.SelectObject(&bmp);
MemDC.SetBkMode(TRANSPARENT);
if (gtest == 0 ){
MemDC.SetTextColor(RGB(255,255,255));
MemDC.DrawText(_T("My Test"),&tRect,DT_CENTER|DT_VCENTER|DT_SINGLELINE);
MemDC.SetTextColor(RGB(255,0,0));
MemDC.DrawText(_T("TEST"),&tRect,DT_CENTER|DT_VCENTER|DT_SINGLELINE);
}
else {
MemDC.SetTextColor(RGB(255,255,255));
MemDC.DrawText(_T("TEST"),&tRect,DT_CENTER|DT_VCENTER|DT_SINGLELINE);
MemDC.SetTextColor(RGB(0,150,0));
MemDC.DrawText(_T("My Test"),&tRect,DT_CENTER|DT_VCENTER|DT_SINGLELINE);
}
pDC->BitBlt(0, 0, tRect.Width(), tRect.Height(), &MemDC,
0, 0, SRCCOPY);
m_Seconds++;
m_TimerEcho.Format(_T("%d: Seconds have passed"), m_Seconds);
gtest ^= 1;
MemDC.SelectObject(oldBitmap);
bmp.DeleteObject();
MemDC.DeleteDC();
ReleaseDC(pDC);
CDialog::OnTimer(nIDEvent);
}
|
|
|
|
|
bmp.CreateCompatibleBitmap(&MemDC, tRect.Width(), tRect.Height());
instead of MemDC there, use the DC that you used as the source for CreateCompatibleDC.
when a memory DC is created, it has a 1x1 pixel monochrome bitmap selected into it. if you create a bitmap compatible with that, you'll get a monochrome bitmap.
also, if you want a background color, you'll need to fill the bitmap with that color (CDC::FillSolidRect)
|
|
|
|
|
Thank you very much.
Now I can see the Text string color is changing.
While, the whole dialog screen is black too, some controls, static texts all disappeared.
Do I need to redraw all the controls like DrawText() ? and then BitBlt()?
The original dialog screen is white.
|
|
|
|
|
whenever i need to draw on a dialog, i put a static 'frame' control in the place where i want to draw. then i get that control's rectangle and limit my drawing to that rect.
CRect outRect;
m_myDrawingRectControl.GetWindowRect(outRect);
ScreenToClient(outRect);
also, you should only do drawing in your CDialog's OnPaint method. if you need to trigger drawing from a timer, just call CDialog::InvalidateRect() with your control's rectangle (as above).
so:
void CDynamicShowTextDlg::OnTimer(UINT nIDEvent)
{
CRect outRect;
m_myDrawingRectControl.GetWindowRect(outRect);
ScreenToClient(outRect);
InvalidateRect(outRect);
}
void CDynamicShowTextDlg::OnPaint()
{
if (IsIconic())
{
...}
else
{
CRect outRect;
m_myDrawingRectControl.GetWindowRect(outRect);
ScreenToClient(outRect);
CPaintDC dc(this);
...
do your drawing here.
use dc as the source for your CreateCompatible* stuff
...
CDialog::OnPaint();
}
|
|
|
|
|
Very very appreciate your help.
|
|
|
|
|
And one more question, even I draw in Timer() function, then WM_PAINT also produced to the system,right?
|
|
|
|
|
|
Hi, I wrote snippet code to test.
first, I put a Static text in the dialog box, from the resource file:
IDD_ECHOBUTTONEVENT_DIALOG DIALOGEX 0, 0, 320, 200
...
BEGIN
...
LTEXT "Static",IDC_STATIC_TXT1,89,59,98,26
...
END
In Ontimer():
CRect outRect;
CStatic* pTxt1Static;
pTxt1Static = (CStatic*)GetDlgItem(IDC_STATIC_TXT1);
pTxt1Static->GetWindowRect(&outRect);
ScreenToClient(&outRect);
InvalidateRect(&outRect);
UpdateData(FALSE);
In OnPaint():
if (IsIconic()) {
...
}
else
{
CRect outRect;
CStatic* pTxt1Static;
pTxt1Static = (CStatic*)GetDlgItem(IDC_STATIC_TXT1);
pTxt1Static->GetWindowRect(&outRect);
ScreenToClient(&outRect);
CPaintDC dc(pTxt1Static);
dc.SetTextColor(RGB(255,0,0));
dc.SetBkMode(TRANSPARENT);
dc.DrawText(_T("My Test"),&outRect,DT_CENTER|DT_VCENTER);
CDialogEx::OnPaint();
}
But, the string "My Test" 's position is not at same position of Static text(IDC_STATIC_TXT1).
offset I guess is about 50 to 100 pixel.
And if I change CPaintDC dc(pTxt1Static) to CPaintDC dc(this), I got nothing, even I stretch the dialog
box to double, triple size.
If I don't use ScreenToClient(&outRect) in OnTimer(), and OnPaint(), I can see "My Test" string, but, need to stretch the dialog;
I set break point, pTxt1Static->GetWindowRect(&outRect); give :
tagRECT = {top=309 bottom=351 left=577 right=724}
run to ScreenToClient(&outRect); give:
tagRECT = {top=96 bottom=138 left=134 right=281}
Could you please help me to see what is the reason?
|
|
|
|
|
econy wrote: But, the string "My Test" 's position is not at same position of Static text(IDC_STATIC_TXT1).
offset I guess is about 50 to 100 pixel.
could that be due to the DT_CENTER|DT_VCENTER flags?
econy wrote:
And if I change CPaintDC dc(pTxt1Static) to CPaintDC dc(this),
it should be CPaintDC dc(this). you're painting the dialog, after all, not the static control.
also, try making your static control a 'frame' type, not a static text. something like:
CONTROL "",IDC_DRAWING_FRAME,"Static",SS_ETCHEDFRAME,12,199,169,66
that gives you a rectangle with no text in it.
|
|
|
|
|
also, it is not essential that you use a static control at all. i use them because having an actual control i can move around in the resource dialog editor makes it easy to do the layout of all the other controls.
but, if you just want to draw at an arbitrary rectangle and skip the GetWindowRect/ScreenToClient/etc. stuff , you can certainly do that, too.
|
|
|
|
|
|
Hi, I want to change a control's color, for example, static text.
logic like:
if test == 0 then
static text color = Red
else
static text color = Green
endif
first I try to do it in OnCtlColor() function, in timer function,
I declared a global variable.
<pre lang="text">
BOOL test = 0;
OnTimer() {
test ^= 1;
}
OnCtlColor() {
if (test == 0 ) {
pDC->SetTextColor(RGB(0,100,0));
}
else {
pDC->SetTextColor(RGB(255,0,0));
}
}
But, the color always be green, not swap.
I knew OnCtlColor need to be trigger with invalidate().
but I don't know how to invalidate a control, not affect it's parent window.
modified 17-Mar-14 7:59am.
|
|
|
|
|
You could try to call CStatic 's Invalidate and UpdateWindow methods.
Veni, vidi, vici.
|
|
|
|
|
|
You are welcome.
Veni, vidi, vici.
|
|
|
|
|
I would like to have a common header file in a simple DLL I am building.
I would like to have common headers, classes forward declarations and their headers in it.
How do I make sure my common header is compiled first?
It seems that the complier works on the classes in a sequence they were added to the DLL.
Any pointers will be as always appreciated.
Cheers
Vaclav
After several attempts to build DirectShow filter using sample code I found here and in SDK I am totally lost how to build simple DLL with more than one class. It appears that having identical include header files in each cpp file compiles / links OK. I even tryied #pragma once and it did not stop this behavior. This leads me to believe that having common file in simple DLL is not possible.
I guess I need some pointers on how this works and why.
The answer:
The sequence of compilation is given in the project DSP file ( VC6.0 )
-- modified 18-Mar-14 11:39am.
|
|
|
|
|
I'm not sure what you are asking here. Header files are used to compile source into object code, they have nothing to do with the final product being a DLL or anything else. In terms of compilation sequence, C/C++ tends to work on a single pass forward direction compilation. That is to say any reference that it comes upon in the source code must have a definition provided earlier in the source. This would be in the current .CPP file or in one of the headers that have been previously included.
|
|
|
|
|
In standard MFC wizard build application there is an option to have precompiled header - StdAfx.h
I put all my forward class declarations and all of my headers ( in proper order ) there.
I would like to do same in simple ( empty ) DLL and build a common header. I suppose I could put this common header in #ifndef / #define / #endif in each header file to avoid multiple definitions.
That way the sequence of compilation would not matter.
|
|
|
|
|
Off-course you should always use header-guards in .h-files:
<br />
<small>#ifndef _FOO_H<br />
#define FOO_H<br />
...<br />
#endif<br />
</small><br />
But what has this to do with making DLLs?
Maybe you have a problem with export & import of the classes+data in those headers? You didn't say, be specific.
-- Gisle V.
|
|
|
|
|
Vaclav_Sal wrote: I would like to do same in simple ( empty ) DLL As I said before, header files have nothing to do with DLLs. The reason for using StdAfx.h in a project is merely to speed up the compilation phase since all the preprocessing of the header files is done once and then saved in internal format that the compiler can quickly read. You can use exactly the same thing in a project that is to create a DLL.
And the sequence of headers does matter, for the reasons I stated earlier, in that all references must have some form of definition before the compiler sees them. It does not matter what type of program (executable, COM component, DLL or static library) you are building, the rules are exactly the same for the language compilation phase.
|
|
|
|
|