|
I'm assuming you're creating a complex control - the one with multiple children hosted in one window. If parent has to take care about painting children, why don't you create a method in the parent called PaintChild and call from within WM_PAINT handler in child window? You don't really need to go low-level and play with messages - with MFC you just don't need to do that.
Tomasz Sowinski -- http://www.shooltz.com
|
|
|
|
|
CParent::OnDrawView(CDC* pDC) is mapped to WM_DRAWVIEW message, which is sent in the CChild WM_PAINT message.
I could call OnDrawView(CDC* pDC) from the childs WM_PAINT handler, but OnDrawView is protected, not public and it would require and upcast i'm sure, which probably has bigger penalties than ::SendMessage().
Using message maps with protected member functions seem to make for more OOP friendly code I thought. As far as CPU expense is concerned. Even if RTTI used in performing upcasts (which i think is required) doesn't consume more clocks it's harder to program and understand. ::SendMessage is simple.
These are my reasons for designing this way...am I missing something...?
Thanx again!
"An expert is someone who has made all the mistakes in his or her field" - Niels Bohr
|
|
|
|
|
Do not map OnDrawView to any messages. Just call it directly. If your children are designed to live only inside your own parent, you can safely use static_cast to get the right pointer:
// in CDudeChild::OnPaint
static_cast<cdudeparent *="">(GetParent())->DrawView(dc);
static_cast is a compile-time construct, it does not cause any performance penalty. Even if you use dynamic_cast instead, it'll be faster than sending message - MFC has to walk through message maps to find the handler. If you're still concerned with every nanosecond (which is a mistake - look for perf improvements where it really matters), you can keep a pointer to CDudeParent in CDudeChild.
My general feeling is that you've spent too much time coding Win32 apps over raw SDK
Tomasz Sowinski -- http://www.shooltz.com
|
|
|
|
|
Tomasz Sowinski wrote:
static_cast(GetParent())->DrawView(dc);
Your absolutely right...only I think I did it like:
((CMyView*)m_pParent)->OnDrawView();
which are the exact same thing I guess, only static_cast is more explicit I would assume.
However, the reason I must use messages was not just for performance. Trying to keep the 2 classes as versatile and re-useable as possible...calling the member functions directly would kinda break this general rule of thumb wouldn't it...?
But mostly...I absolutely have too...cuz...well OnDrawView is a protected member function.
"An expert is someone who has made all the mistakes in his or her field" - Niels Bohr
|
|
|
|
|
|
I don't see how this is possible, i'm missing something here.
If I had:
#define WM_CUSTOMMSG WM_USER+1
class MyClass
{
MyClass(){ }
...and so on
};
BEGIN_MESSAGE_MAP(CView, MyClass)
ON_MESSAGE(WM_CUSTOMMSG, OnCustomHandler)
END_MESSAGE_MAP
If I included this control as well as a third party control which by chance did the exact same thing
WM_USER+1, how would the two seperate, but equal #defines not clash...???
if the WndProc was like this:
WndProc()
{
switch(nMsg)
{
case WM_MYMSG;
break;
case WM_YOURMSG:
break;
}
}
This is why i'm confused...if my app had 2 seperate libs which both did the WM_USER+1 how would my app be able to distinguish which message was really sent...?
Thanx Mike
"An expert is someone who has made all the mistakes in his or her field" - Niels Bohr
|
|
|
|
|
Message is handled by the control - so when it receives (WM_USER+n) it will know exactly what's going on.
Tomasz Sowinski -- http://www.shooltz.com
|
|
|
|
|
of course...duh...why didn't I see that in the first place...
The messages are internal to the parent and child classes (control). I think I finally got it...thanx
Cheers
"An expert is someone who has made all the mistakes in his or her field" - Niels Bohr
|
|
|
|
|
of course...duh...why didn't I see that in the first place...
Don't you just hate when that happens.
Some days the "Obvious Bus" could be parked in front of my house with a beeping horn and I would still miss it.
Tim Smith
I know what you're thinking punk, you're thinking did he spell check this document? Well, to tell you the truth I kinda forgot myself in all this excitement. But being this here's CodeProject, the most powerful forums in the world and would blow your head clean off, you've got to ask yourself one question, Do I feel lucky? Well do ya punk?
|
|
|
|
|
I don't see what you're asking. Your CWnd-based control (which is entirely under your control (sorry, can't think of a better wording)) can handle any WM_USER+n messages it likes. That is totally unaffected by other controls in the program.
For instance, your app can send WM_USER+1 to your control for one thing, and send SB_SETTEXT (which is WM_USER+1) to a status bar (a totally different control) with no problems.
--Mike--
Best score on the mini-putt game: 30
My really out-of-date homepage
Sonork - 100.10414 AcidHelm
Big fan of Alyson Hannigan and Jamie Salé.
|
|
|
|
|
Hey Mike...thanx for helping me clear that up.
I've got it figured out now...i dunno why it wasn't sinking in...
Thanx again!
"An expert is someone who has made all the mistakes in his or her field" - Niels Bohr
|
|
|
|
|
What happened to Brief and Epsilon editor emulation? Were they
completely removed from VS.NET?
|
|
|
|
|
I'm little blurry about the purpose of PreTranslateMessage so can someone clear it up for me if i'm wrong.
This function allows you to basically emulate the message pump of an SDK program...?
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
is basically:
CMyView::PreTranslateMessage(MSG* pMsg)
{
if(pMsg->message == WM_PAINT)
{
if(pMsg->lParam == 1000)
else
}
}
Do I call DispatchMessage directly from with the PreTranslateMessage() or do I call the default CView::PreTranslateMessage()
Can I change the message a little before sending it off to WndProc...?
Basically in the above code i'm trying to accomplish the following:
1) WM_PAINT message received THEN
2) Check lParam for user-defined value
3) if lParam==VALUE THEN
Change DC to another DC
else
Prevent message from getting to WndProc.
I think WM_PAINT actually can't be stopped until BeginPaint is called, which will remove it from the queue.
I hope I was clear on the effect I am after and I hope even more that someone understands me and can offer suggestions or advice.
Thanx!
"An expert is someone who has made all the mistakes in his or her field" - Niels Bohr
|
|
|
|
|
Your code segment would work, and yes you could change the message a little, not send it forward at all, or even change the message itself to something entirely different. The main issue is making sure that people who may want to use your class or control in the future understand the behavior.
I should also say, that it is not very wise to send your own WM_PAINT messages, if this is how you intend on getting the user defined value in the lParam. Maybe create your own user defined paint message.
HockeyDude wrote:
I think WM_PAINT actually can't be stopped until BeginPaint is called, which will remove it from the queue.
If you want to stop WM_PAINT message from being sent, you can simply call ValidateRect(hWnd, NULL) . WM_PAINT messages are not really entered into the message queue, GetMessage or PeekMessage for that matter will send a WM_PAINT message directly to the target window only when there are no other posted messages left in the message queue.
If you call ValidateRect(hWnd, NULL) after you have performed the painting that you are interested in, then a WM_PAINT message will never be generated.
|
|
|
|
|
Thanx again Kilo.
I've only re-designed the friggen thing about 6 times now...each time it gets better and better naturally.
I always get so far, only to realize it's not possible...
But I think of a better and possibly easier way of doing things. I'm really trying to keep the control packaged nicely, not so much in fear of anyone using my class, but just for the experience. It's easier for me to use also.
It's this one hurdle that is stopping me in my tracks time and time again, causing me to re-think and re-design.
The parent class I want to do all the drawing, but it already draws the control, so any overriden OnDraw will stomp on the control UI. I thought i'd fix this problem by creating a child window which would also provide clipping, whenever the child gets WM_PAINT it would re-direct it to the parent...and i'd use OnErase for the control appearance UI. The approach which I (think) finally decided on, which is IMO is the best approach, is to just use another virtual function like CParent::OnDrawView() which will respond to the custom message WM_DRAWVIEW sent inside the child's ON_PAINT with the childs CDC* as well
This way drawing can still be done with a virtual function of the parent class. Only problem i'm having now
Is how to map a custom message...?
And should I use WM_USER+1 or RegisterWindowsMessage()
Thanx again!
"An expert is someone who has made all the mistakes in his or her field" - Niels Bohr
|
|
|
|
|
ON_MESSAGE macro...
that was easy...
Thanx again!
"An expert is someone who has made all the mistakes in his or her field" - Niels Bohr
|
|
|
|
|
Hi, i'm trying to check if a port is open in a remote PC, i'm using Winsock API with non-blocking sockets. When i call connect(...) this function doesn´t give me a code if the remote port is open. How can i assure that the port i'm looking for is open??
Tnx
|
|
|
|
|
If you can connect to that port, the port is open.
If connect() fails, it might be that the port is not open, though it could also be a firewall...
Nish
It's seven o'clock
On the dot
I'm in my drop top
Cruisin' the streets - Oh yeah
I got a real pretty, pretty little thing that's waiting for me
|
|
|
|
|
In particular the deque class. If I have multiple threads doing pop_front() s and front() s and others at the same time, will I be in trouble, or is the class thread-safe? Do I have to do my own synchronization code?
Tx
Michel
Michel
If I am wrong or said something stupid, I apologize in advance
|
|
|
|
|
If you do pop_front()s and front()s from multiple threads on the same deque object at the same time, you'd better do some synchronization.
I vote pro drink
|
|
|
|
|
first if this is in twice i am sorry
is there a way to programmatically select an item in a list control and highlight it.
(my view = report)
thank you.
|
|
|
|
|
ctrlList.SetItemState(nItem, LVIS_SELECTED, LVIS_SELECTED);
ctrlList.SetItemState(nItem, LVIS_FOCUSED, LVIS_FOCUSED);
ctrlList.SetItemState(nItem, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
farewell goodnight last one out turn out the lights Smashing Pumpkins, Tales of a Scorched Earth
|
|
|
|
|
If you want to advertise, then pay, and support codeproject. Otherwise p!ss off.
Sorry to dissapoint you all with my lack of a witty or poignant signature.
|
|
|
|
|
Nish
It's seven o'clock
On the dot
I'm in my drop top
Cruisin' the streets - Oh yeah
I got a real pretty, pretty little thing that's waiting for me
|
|
|
|
|
There has to be a more ethical way of free advertising. My friend...I think, you may have made worse for yerself. Notice the comments...if you wanna advertise...pay for it and support our favourite site.
If you can't afford to advertise or care not to...then maybe do it indirectly and still support CodeProject.
Post some code used in your app as examples that others can learn from and use themselves. Certainly this isn't ideal for commercial products cuz you loose your proprietorship and people could use that code for there own apps to compete against yours (I think most are pretty respectful though).
However If your an established commercial vendor you SHOULD have the money to pay for advertisments. If your a struggling small time business then, maybe post some cool code, and indirectly get people interested in your product.
I'm positive this would work better on the CP human psyche cuz well your wasting everyones time advertising here. Which is only gonna make people NOT want to buy your product. But if you shared some sweet code, people liked it...and then noticed it's a small portion of a much better larger product...you might get some bytes (pun intended).
IMFO... I finally used the damn acronym...Yippee!!!
Cheers!
"An expert is someone who has made all the mistakes in his or her field" - Niels Bohr
|
|
|
|