|
Thanks for the explanation. However, OnSetFont receives a pointer to the CFont; it can not pass back a new CFont. I was already so far, that I displayed the current font attributes (GetLogFont) and created a new CFont - but I can't tell MFC to use this CFont.
|
|
|
|
|
Most interesting.
Apparently 'OnSetFont' didn't work as straightforward as I had understood from the MFC Reference. It seems that this handler can't be used to override the passed font object, because in doing so, the program asserts in the end. Why this happens is currently still unclear to me.
However, I've already found a few alternates, but they require you to alter the font for each and every control of your dialog box seperately. Go to your main application, and force a creation of modeless dialog box. Once the box is created, get a control ID inside it (GetDlgItem), and call this returned pointer's 'SetFont' method, issuing an address of a precreated CFont.
If a modeless dialog box is not an option, then create a dynamic CFont object in your dialog's constructor by using a LOGFONT structure with values you specify. Don't forget to zero the structure before using it. Then call 'GetDlgItem' in your dialog's WM_PAINT handler and the result's 'SetFont' to give it a new font. Remember to delete the Windows font object and release the dynamic CFont object, e.g. in your dialog class's destructor.
In all cases, remember to check your app for memory leaks, they tend to become easy with these things
-Antti Keskinen
----------------------------------------------
The definition of impossible is strictly dependant
on what we think is possible.
|
|
|
|
|
Thanks; unfortunately, this is not a solution to my problem. I did not want to complicate things with this detail, but seemingly I should have posted this: setting the fonts is not the real issue for me; I'm doing this for several controls anyway.
The "real" issue with the default font of the dialog is, that it's size determines the pixel size of the window and all controls; the x- and y-units are deducted from the average width and height of the window's font (I remember something that the y-unit is half of the font's "em-height", and the x-unit is a quarter of the character cell width).
With changing the font, I wanted to be able to change the size of everything in the dialog; I want to offer a "calibration" to the user, to adjust the window size depending on the monitor resolution and size as well as the magnification factor. See DPI (a misnomer) in Display properties", "setting", "advanced". I don't display any bit maps, just because of the distortion they cause when displayed with different settings.
Changing the font size makes Windows to recalculate everything, proportional. Any other method would work only if the program calculated not only the sizes, but the positions of the controls as well - and that's a lot of work (and it would convert the application to a dialog wizzard :^(.
I don't give it up (yet), for I find that this should be a natural way to customize an application. I find it dreadful, when an application becomes a "miniature" on a high-resolution monitor, or it "grows" out of the monitor, controls become unaccessible, etc. at low resolution.
Anyway, thanks for your effort. I'm sorry not to have started out with the precise specification of my problem.
|
|
|
|
|
I need to update data of an MFC object declared in one thread from with in an other
thread.............. This needs to be done throug handles... as described by MSDN.............
but i am not finding the required result............ can someone please make a simple Dialog Application
........... with a worker thread to update data on the Dialog....... and send it to me....
..... so that i will be in a better position to understand where i am mistaking........ i have
already wasted lot of time over this but invain...........
Ever Welcome...
|
|
|
|
|
I am trying to make a feature for one of my programs that works somewhat like the CFileDialog, however they are not close enough that I can simply derive from that class. Can someone tell me how I can find out what files and folders are in a specific folder?
Example: C:
Folder 1: Program files
Folder 2: Windows
etc.
I need to be able to do this from any place too. So if I pick "Program Files" from C:\, I then need to be able to find out what files and folders are in it...
I am sure there is some simple easy function that does this, I just can't seem to find it.
Thanks a lot!
If you have a problem with my spelling, just remember that's not my fault. I (as well as everyone else who learned to spell after 1976) blame it on Robert A. Kolpek for U.S. Patent 4,136,395.
|
|
|
|
|
|
i have a custom control that is derived from a CWnd class. I'd like to add a button to the control, but I'm not sure if i should manually draw the button in my paint method or just include a cbutton instance. what do people normally do? if i were to include a cbutton to my control, where would i actually *create* the button and place it in my control?
thanks in advance,
|
|
|
|
|
I'm a 'purist' MFC dude, so I wouldn't mix API and MFC together (CWnd with custom painted buttons (Non-CButton's))
Short explanation:
Use CButton as a static member of your CWnd-derived class. Call it's 'Create' in your derived class's WM_CREATE handler, and leave 'WS_VISIBLE' style out. Display and position the button with SetWindowPos in your WM_PAINT handler. The 'DestroyWindow' should be called automatically for all child windows when WM_DESTROY is posted to your CWnd-derived class's window object's message queue. To make sure, call it yourself in your WM_DESTROY handler.
Detailed explanation:
First, add a static member CButton m_TheButton to your class's header file, and order your constructor to call the CButton's constructor, if necessary. You can also create a CButton pointer and use 'new' to create a dynamic button. Both solutions are fine, the latter being a bit more flexible memory-wise.
Now, your constructed class contains a constructed CButton object. To create the button control, you call this member's 'Create' function, and specify the control's properties (Is child, parent is your control / Sends messages to parent etc etc). Note that when you create the button, you don't need to make it visible. See below.
A good place to call Create for the button control would be in the WM_CREATE message handler of your parent. There, you would create the button, specifying it as non-visible (leave WS_VISIBLE out). Next, go to your WM_PAINT handler, and in there use SetWindowPos to position the control to it's correct place, giving it the correct size, and making it visible. This way, the button is 'Created' only once, but if your window gets repainted, the button will remain in it's specified position and size.
Now, if you write a message handler for WM_COMMAND and make it check if the ID is the button's ID, you can handle messages caused by the user clicking on the button. As the custom control is the parent, the WM_COMMAND messages are posted to it's queue. So, overwrite WM_COMMAND handler for your custom control.
Hope this helps. If it doesn't, I can write a small app which demonstrates "a CWnd object which has a CButton child in it's middle" for you
Note that if you need to use the custom control inside a frame window (SDI Frame, for example), then you should derive it from CCtrlView instead of CWnd. CCtrlView supports all "views which have controls inside them". The Tab Window control (Window with tabs to select different views) is a perfect example of this. CCtrlView is a parent for views such as CEditView (View with Edit control) etc.
If you need, I can write an example of this also, it's good practise
Greets,
Antti Keskinen
----------------------------------------------
The definition of impossible is strictly dependant
on what we think is possible.
|
|
|
|
|
thanks for your detailed explanation. I have tried what you've described here, but it flickers alot when my control refreshes its display. i know that it's definitely the extra button on top of my existing control that's causing the flicker, and i'm not sure what to do.
CMyControl::OnPaint()
{
drawSomeStuff(); //i used Keith Rule's CMemDC in these drawing routines already
drawSomeMoreStuff();
m_button1.SetWindowsPos(&CWnd::wndTop....)
}
|
|
|
|
|
Well, I made a small miscalculation in my first reply. To explain it a bit, let's dive into the way stuff is handled in Windows.
You might already know (and if you didn't, now you do) that everything in Windows are windows. Sounds like an idiodome, but it is the fact. For example, our notorious button control is a WINDOW placed OVER a portion of parent view's area (custom control's client area).
So, you need to remake the original Create call to actually include the WS_VISIBLE style for the button. Now, after you have created the button, issue a SetWindowPos, placing the button window AFTER the control's view (first parameter to 'this'), and flagging it to SWP_HIDEWINDOW. You can ignore the size and position parameters by putting the necessary flags in the call (SWP_NOSIZE | SWP_NOMOVE, I think).
Now, when you need to show the button on your control, call it's ShowWindow with SW_SHOW flag. Note, that this call should only be made in a function which is not repeatedly called.
To clarify, consider the hiearchy we have created now. There is the custom control. It has a view. You can draw into this view (device context), displaying lines, texts, rectangles, everything you need to make it look cool. Then, you place new small window objects to represent different types of controls (Edit control, button control, hell, even a static control is a window).
This hiearchy understanding is especially relevant if you use custom-skinned windows (Common trait in custom control creation). Those could have a background image, with black rectangular holes where the controls will be. Then, they might have custom-drawn controls like bitmapped buttons, to fill those holes and fit seamlessly into the control's view.
For the code part you posted: remove the m_button1.SetWindowPos call from the WM_PAINT handler. Instead, hide it in the creation phase, and move this creation to the OnCreate-handler INSTEAD of OnCreateClient, if it is currently there.
The OnCreate-handler is called when the window representing your custom control is created. That is correct, we want to create and hide the button control when the window is being created. The OnCreateClient -handler (which is called to create the VIEW inside the window) can then display the control, if you want it to be visible as soon as the control window is shown. Remember to call the display function as the last thing in OnCreateClient, after everything else is drawn.
-Antti Keskinen
----------------------------------------------
The definition of impossible is strictly dependant
on what we think is possible.
|
|
|
|
|
I am creating a dialog based application that loads from an XML configuration file. So, you don't know at run-time how many or which type of objects will be used. The objects that can be created are custom defined using GDI+ and include labels, buttons etc. A button maybe associated with a call to initialize a dll. My need is that each item loaded from the config file will need to do several things 1) Draw themselves 2) Hit testing.
So finally, on to my question. How can I dynamically load lets say 3 buttons and 3 labels and have them do their required functions.
During testing I am doing the following steps at compile time
1) creating the objects in OnInitDialog() CLabel* pLabel = new CLabel;
2) in my draw function I am adding pLabel->Draw()
3) in LButtonDown I am adding if(pLabel->IsHit()).... do something
So, I need to somehow keep list of buttons and list of labels then in the Draw() function for example I to say while( there are buttons) Draw yourself.
How would you go about tackling this?
Hope that makes since.
|
|
|
|
|
IS there a base class for all these controls ? You need to keep a list of an object that is either a base class or a facade for the objects you want, and then loop through them to do anything with them. I'd have thought that by making the controls children of your window, they would draw themselves though.
Christian
I have drunk the cool-aid and found it wan and bitter. - Chris Maunder
|
|
|
|
|
Christian,
I used the term control rather loosely. There is no base class for my controls.
They are just visual representations. The buttons are either bitamps or a
roundedrect for which I create a region for hit testing. So, they are not based
on any real control or window.
Actually I have looked at all of your GDI+ articles so thanks for writing them.
So, your saying keep a list of each kind of objects for example.
1) CLabel
2) CTextButton
3) CBitmapButton
If I create 3 CTextButton's
CTextButton* pTextBtn1 = new CTextButton; // arguments not shown for simplicity
CTextButton* pTextBtn2 = new CTextButton;
CTextButton* pTextBtn3 = new CTextButton;
I don't understand how to create a dynamic list of CTextButton's for looping thru.
Sorry for being so dense.
PS: As a side question how do you determine the length of text that you have drawn?
I am trying to draw some text (ie Friday, November 3, 2003 10:59 PM ) then find the
bounding rect for it so that I can invalid the rect for smooth updating. Since font
type is user configurable the size of the bounding box varies. I know how to find
the height of a font but I have not figured out how to find the width.
|
|
|
|
|
smesser wrote:
So, your saying keep a list of each kind of objects for example.
No, I'm saying keep one list of all objects, by deriving them all from a base class which defines the common functionality, such as a Draw() method.
smesser wrote:
I don't understand how to create a dynamic list of CTextButton's for looping thru.
Sorry for being so dense.
Look up my STL articles, basically you put them in a std::list or std::vector, and then use for_each to step through them and call the required method, such as Draw in OnPaint.
smesser wrote:
PS: As a side question how do you determine the length of text that you have drawn?
A HDC or CDC has a method for doing that, but I don't recall what it's called, sorry.
Christian
I have drunk the cool-aid and found it wan and bitter. - Chris Maunder
|
|
|
|
|
I see what your saying. I have not used STL but I guess it's time I start.
thanks for your input.
|
|
|
|
|
GetTextExtent and friends.
Steve S
|
|
|
|
|
Hi!
I write a MDI application to show large images. I also need a windows to show the overview of whole image. I dont know the best way to do it.
One thought is build a spliter window, but that will waste some space. Because the overview is small, for example 128*128, when take a vertical splitter the remaider space (640-128)*128 will be wasted.
Another is Draw the detail image and then draw the overview on left upper corner in OnDraw. But in my application, the image is draw by tile, not in once, so this method can't be accepted.
Third I think is best. A float window always on top of image views, I can show the overview in it. But i dont' know how to realize it. Is there any resource and code I can take as a reference?
Any idea?
Thank you!!
|
|
|
|
|
When I activate my window,my window will not hide the other application window.like when you activate the win2k's desktop,you can see the application
you have run.
|
|
|
|
|
How can the text, which appears on the button in the taskbar, be changed without changing the window's title bar?
|
|
|
|
|
Hi
After all those hard things that I did to make this software, I faced a stupid error which stoped me.
I have two classes, these two need each other in their definition structure. So I've included the first one's header file in the second one's and vice versa. At this point an error appeared which says:
warning C4182: #include nesting level is 362 deep; possible infinite recursion
fatal error C1076: compiler limit : internal heap limit reached; use /Zm to specify a higher limit
I know what does it say and it's completely logical but I don't know how to solve it. I need a practical advice.
Thanks...
|
|
|
|
|
In the header for each class, use a forward declaration of the other class instead of including the header, e.g.:
class MyClassB;
class MyClassA {
} Then, include the other class's header in the .cpp file.
#include "MyClassA.h"
#include "MyClassB.h"
- Mike
|
|
|
|
|
Put this in class A's header, at the top:
class B;
then include the header file in the .cpp file, do the same on the other side. Then both headers know that the other class exists, which should be all they need to know.
Christian
I have drunk the cool-aid and found it wan and bitter. - Chris Maunder
|
|
|
|
|
I have an app that can either be a chat client or a chat server.
I can run two instances of the app and use one a a client and one as a server.
I have them configured to use the local loop, but, when I send a message, it works fine but the 'OnRecieve' function in the server never gets called.
This is actually a program out of a book.
I can send the code if anyone can help.
Thanks!
|
|
|
|
|
how do you clear a file, in plain c++ (console) and how do you put something into a buffer and then flush it to a file... again in c++(console), help. THX
<marquee>Universal Project... Soon to be a .net
|
|
|
|
|
See the description of the mode argument in the fopen() documentation.
Use fflush() to flush the buffer, but remember that calling fflush() will not guarantee that data is written to disk if you have write caching enabled on your system.
/ravi
Let's put "civil" back in "civilization"
Home | Articles | Freeware | Music
ravib@ravib.com
|
|
|
|
|