|
Hi,
Unfortunately I could not get this to work either. Do you have any other ideas? This is being run on Win CE by the way.
I didn't put the transparency stuff in the last post, but it comes just before the text is printed. A global region is made in the constructor with bits missing (missing bits are therefore transparent). The images are loaded into a CBitmap array. In OnPaint;
To display the BMP;
Create CDC from DC
CDC select object (global/main region)
CDC select object (bitmap)
TransparentBlt to DC;
TransparentBlt(dc.GetSafeHdc(), 0, 0, floatingBMP.bmWidth, floatingBMP.bmHeight, myCDC->GetSafeHdc(), 0, 0, floatingBMP.bmWidth, floatingBMP.bmHeight, 0x00ff00);// Transparency = lime green, altho this doesnt matter as the region has already been created to take this into account;
After this is the DrawText code which has already been show.
Any ideas?
Thanks
MS.
|
|
|
|
|
Without knowing what's not working...
Mr Simple wrote: Create CDC from DC
How are you doing this? It should be a memory DC created with CDC::CreateCompatibleDC().
Mr Simple wrote: CDC select object (global/main region)
What's the purpose of the region - for clipping? Why select it into the source DC?
That looks suspicious...I would try commenting the region stuff out and see what happens.
Are you handling WM_ERASEBKGND? If so, what are you doing there?
What do you want to see and what is happening that is wrong?
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Hi,
I am using CreateCompatibleDC;
<br />
CPaintDC dc(this);
CDC *floatCDC = new CDC;<br />
floatCDC->CreateCompatibleDC(&dc);
I have removed the region code, and can report having it there made no difference to my application. I had read about it in a 'funky shaped window' article and assumed I needed it, obviously I was wrong
I am not handling WM_ERASEBKGND.
What I want to see is text moving on a transparent background. I have manged this to a degree, however when the text is moved, the old text remains underneath the new text. I think part of the problem is that I am drawing over the old text with a transparent image, so the old text is still visible.
Any other ideas?
Thank you for your time!
MS
|
|
|
|
|
Here's a working example, moving text with a timer across a bitmap background.
This is implemented on a simple dialog with just an ok button. The same code would work in
a CWnd-derived class - In that case, WM_CREATE/OnCreate would be used instead of
OnInitDialog()...
#pragma once
#include <atlimage.h>
class CMovingTextDialog : public CDialog
{
DECLARE_DYNAMIC(CMovingTextDialog)
public:
CMovingTextDialog(CWnd* pParent = NULL);
virtual ~CMovingTextDialog();
enum { IDD = IDD_DIALOG2 }; <font color="Red">
protected:
virtual void DoDataExchange(CDataExchange* pDX);
DECLARE_MESSAGE_MAP()
public:
virtual BOOL OnInitDialog();
protected:
virtual void OnOK();
public:
CImage BkImage;
UINT_PTR MoveTimer;
CString TextStr;
CSize TextSize;
CRect TextRect;
afx_msg void OnPaint();
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
afx_msg void OnTimer(UINT_PTR nIDEvent);
};
#include "stdafx.h"
#include "MFCTester.h"
#include "MovingTextDialog.h"
IMPLEMENT_DYNAMIC(CMovingTextDialog, CDialog)
CMovingTextDialog::CMovingTextDialog(CWnd* pParent )
: CDialog(CMovingTextDialog::IDD, pParent)
{
BkImage.Load(_T("e:\\test.bmp")); <font color="Red">
MoveTimer = 0;
TextStr = _T("Moving Text");
TextSize.cx = TextSize.cy = 0;
TextRect.SetRect(0,0,0,0);
}
CMovingTextDialog::~CMovingTextDialog()
{
}
void CMovingTextDialog::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CMovingTextDialog, CDialog)
ON_WM_PAINT()
ON_WM_ERASEBKGND()
ON_WM_TIMER()
END_MESSAGE_MAP()
BOOL CMovingTextDialog::OnInitDialog()
{
CDialog::OnInitDialog();
MoveTimer = ::SetTimer(*this, (UINT_PTR)12345, 10, NULL);
return TRUE;
}
void CMovingTextDialog::OnOK()
{
::KillTimer(*this, MoveTimer);
MoveTimer = 0;
CDialog::OnOK();
}
void CMovingTextDialog::OnPaint()
{
CPaintDC dc(this);
if (0 == TextSize.cx)
{
TextSize = dc.GetTextExtent(TextStr);
TextRect.SetRect(0, 0, TextSize.cx, TextSize.cy);
TextRect.InflateRect(4, 4);
}
dc.SetBkMode(TRANSPARENT);
dc.DrawText(TextStr, &TextRect, DT_LEFT | DT_TOP);
}
BOOL CMovingTextDialog::OnEraseBkgnd(CDC* pDC)
{
CRect ClientRect;
GetClientRect(&ClientRect);
BkImage.StretchBlt(*pDC, 0, 0, ClientRect.Width(), ClientRect.Height());
return TRUE;
}
void CMovingTextDialog::OnTimer(UINT_PTR nIDEvent)
{
if (0 != TextSize.cx)
{
InvalidateRect(&TextRect);
CRect ClientRect;
GetClientRect(&ClientRect);
TextRect.OffsetRect(2, 2);
if (TextRect.right > ClientRect.right || TextRect.bottom > ClientRect.bottom)
{
TextRect.SetRect(0, 0, TextSize.cx, TextSize.cy);
TextRect.InflateRect(4, 4);
}
UpdateWindow();
}
CDialog::OnTimer(nIDEvent);
}
What's different from what you are doing?
Mark
|
|
|
|
|
Hello,
The only major difference is that I am not using CImage, as I need to be able to TransparentBlt which I have been told there are problems with on WinCE. I converted your code closer to my existing (using CBitmap, transparency, removing erase bkground) and it worked great. Then I made my existing code practically idential, and it still didn't work
The only thing I can find different is the way I create the window. I have a method in the class called "CreateFloaterWnd" (parent as parameter) which loads the bitmap, gets it's size, then calls CWnd::CreateEx, positioning itself relative to the parent's X/Y location.
I will try to convert it to use a dialog and see what happens. I still dont understand how this could be the problem though.
Thank you very much for your effort!!
MS.
|
|
|
|
|
Hmmm I don't know about WinCE unfortunately.
CImage wraps a little GDI+ for loading and saving, and also wraps a
HBITMAP/DIBSection, which works with TransparentBlt() just fine (in
fact, the class has a TransparentBlt() method). Again, I'm not sure about
WinCE compatibility though.
If you have a little project that doesn't work that I can test on regular
Windows I'll check it out.
Good luck
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Hi,
Everything in normal windows can be done in CE, sometimes you just need to go about it a bit differently.
I have cut out everything from my project and managed to write a non-working class if you are interested. I wont have access to CE again until monday so wont be able to test the dialog thing yet.
Below is the code, it is very simple as you can probably see. Just call the .CreateTransparent(this); and you should get a nice streak down the form.
Once again, thanks for your help!
MS.
The .H;
<br />
class CNotWorking :<br />
public CWnd<br />
{<br />
public:<br />
CNotWorking(void);<br />
~CNotWorking(void);<br />
void CreateTransparent(CWnd *pParent);<br />
<br />
DECLARE_MESSAGE_MAP()<br />
afx_msg void OnPaint();<br />
afx_msg void OnTimer(UINT nIDEvent);<br />
<br />
private:<br />
CRect rTextRect;<br />
UINT tTicker;<br />
<br />
};
//////////
And the .CPP;
<br />
BEGIN_MESSAGE_MAP(CNotWorking, CWnd)<br />
ON_WM_PAINT()<br />
ON_WM_TIMER()<br />
END_MESSAGE_MAP()<br />
<br />
<br />
CNotWorking::CNotWorking(void)<br />
{<br />
rTextRect.SetRect(0, 0, 40, 20);<br />
tTicker = 0;<br />
<br />
}<br />
<br />
CNotWorking::~CNotWorking(void)<br />
{<br />
}<br />
<br />
void CNotWorking::CreateTransparent(CWnd *pParent)<br />
{<br />
CWnd::CreateEx(NULL, NULL, _T("Transparent"), WS_CHILD, 20, 20, 500, 500, pParent->GetSafeHwnd(), NULL);<br />
<br />
tTicker = ::SetTimer(*this, (UINT_PTR)12345, 20, NULL);<br />
<br />
ShowWindow(SW_SHOW);<br />
}<br />
<br />
void CNotWorking::OnPaint()<br />
{<br />
CPaintDC dc(this);
<br />
<br />
dc.SetBkMode(TRANSPARENT);<br />
CString textStr = "test";<br />
dc.DrawText(textStr, &rTextRect, DT_LEFT | DT_TOP);<br />
<br />
<br />
}<br />
<br />
void CNotWorking::OnTimer(UINT nIDEvent)<br />
{<br />
InvalidateRect(rTextRect);<br />
rTextRect.OffsetRect(0, 2);<br />
UpdateWindow();<br />
<br />
CWnd::OnTimer(nIDEvent);<br />
}
|
|
|
|
|
Your code works for me.
In OnTimer(), I had to change
InvalidateRect(rTextRect);
to
InvalidateRect(&rTextRect);
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Mark Salsbery wrote: Your code works for me.
Really???
I have tried both but I still get the smudge either way (I have only tested on XP).
|
|
|
|
|
Yes, really
The change I made wasn't even necessary, since CRect has a LPRECT
operator.
I'm testing on Vista.
Is it leaving a trail of pixels or does the entire text get left
behind on previous draws?
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
The entire text gets left behind (in the image below I have used 'rTextRect.OffsetRect(0, 20);' to space them out a bit to show this).
http://i19.tinypic.com/8a4gh2w.jpg
Thanks
MS.
|
|
|
|
|
Hmm that shouldn't happen
WM_ERASEBKGND should redraw the background for the invalidated
rect when the CPaintDC is created (during the internal call
to BeginPaint().
Can you add a WM_ERASEBKGND that calls the base class method?
Then in that handler, maybe draw a rectangle at the textrect.
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Mark Salsbery wrote: you don't need to preserve a DC between WM_PAINT messages.
ummm.... don't you mean you should not?
|
|
|
|
|
led mike wrote: don't you mean you should not?
For the sake of this thread - yes.
Discussing owned DCs is beyond the scope of the problem/OP/thread, IMO
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Are you using Invalidate () before calling UpdateWindow () ??
It mades the drawing surface to be erased and then repainted, so the old text will be away, and just the new "repositioned" will be drawn.
Greetings.
--------
M.D.V.
If something has a solution... Why do we have to worry about?. If it has no solution... For what reason do we have to worry about?
Help me to understand what I'm saying, and I'll explain it better to you
“The First Rule of Program Optimization: Don't do it. The Second Rule of Program Optimization (for experts only!): Don't do it yet.” - Michael A. Jackson
|
|
|
|
|
As the subject says,
I'm building a virtual keyboard on a WINCE 5.0 device.
I'm stuck with the function keys (CTRL,SHIFT,CAPS,ALT).
I know that I gotta change some flags, but how?
I have tried SendVirtualKey(VK_CAPITAL,KeyShiftCapitalFlag); // doesn't work
and also SendVirtualKey (VK_CAPITAL,KEYEVENTF_KEYUP) // doesn't work
and also SendVirtualKey (KeyShiftCapitalFlag,KEYEVENTF_KEYUP) doesn't work
Any suggestions?
Thank you!
|
|
|
|
|
hi,
how to use multi column combo box in a dialog? how can add strings into the multi column combo box. actually i was used this code
m_ComboBoxControl1.AddRow(ColumnString0, ColumnString1);
but it was not functioning.
can you please help me
Thanks,
Panthal
|
|
|
|
|
Forgive my ignorance....what multi-column combobox?
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Mark Salsbery wrote: what multi-column combobox?
...looks around cautiously...
Psst, Mark. It's the one over there.
"Normal is getting dressed in clothes that you buy for work and driving through traffic in a car that you are still paying for, in order to get to the job you need to pay for the clothes and the car and the house you leave vacant all day so you can afford to live in it." - Ellen Goodman
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
|
|
|
|
|
hmm...
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Hello everyone,
I can not understand how the following code works and assign 100 to counter variable?
void Foo (int* input)
{
*input = 100;
return;
}
#define GETFOO (Foo( &counter ), counter)
int counter;
int main()
{
GETFOO;
return 0;
}
thanks in advance,
George
|
|
|
|
|
the macro expands to
(Foo( &counter ), counter);
on running:
Foo(&counter) is first evaluated and it sets counter=100 , then counter is evaluated giving the result 100 to the expression inside the outer braces, finally the result itself it is discarded.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
|
|
|
|
|
Thanks CPallini,
I do not understand how this statement works,
(Foo( &counter ), counter);
I have tested that the simple statement (without comment) also works. What is the benefit and function to add , and counter in macro definition?
// #define GETFOO Foo((&counter), counter)
#define GETFOO Foo(&counter)
regards,
George
|
|
|
|
|
George_George wrote: I do not understand how this statement works,
(Foo( &counter ), counter);
Both I and toxcct gave an answer to the above.
George_George wrote: I have tested that the simple statement (without comment) also works.
Of course.
George_George wrote: What is the benefit and function to add , and counter in macro definition?
The difference stands in the returned value of the expression, for instance
void Foo (int* input)
{
*input = 100;
return;
}
#define GETFOO (Foo( &counter ), counter)
void main()
{
int i = GETFOO;
}
will assign 100 to i .
Anyway that way of coding is simply junk.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
|
|
|
|
|
Cool CPallini,
Thanks!
regards,
George
|
|
|
|
|