C++/CLI Visual C++ 2010 Express - Drawing different shapes inside one panel - c++

I got a problem. There is panel1 which i want to use as my paiting window. And i also have 2 buttons. One should draw "fillRectangle" in the middle of panel and second one should draw "fillellipse" next to it. I dont have the problem with drawing itself
Color aColor = Color::FromArgb( 255, 0, 0 );
SolidBrush^ aBrush = gcnew SolidBrush(aColor);
Rectangle rect = Rectangle(x, y, 10, 10);
e->Graphics->FillEllipse(aBrush, rect);
But i want to know, how to make that pressing each button draws different shape inside panel. Do i need to put both, ellipse and rectangle in panel1_Paint and use flags like...
if(ellip == 1) FillEllipse;
if(recta == 1) FillRectangle
which are set using buttons? I hoped i can code drawing part inside button or function, and then somehow refer to that panel. Is it possible?

If you want the buttons to have their own painting routines, then they draw themselves and your panel is unnecessary, in terms of drawing anyway, they'll have their own canvas.
If you want a panel that draws shapes on itself dependant on some property, then yes you go down something like the route you suggested, though I'd be tempted by some sort of shape class even if it wasn't a control. Would make adding other shapes or more of a shape much easier.
You could have panel carry a collection of shapes that implement say IDraw which takes a Graphics reference, and then just iterate through them and call it with Panel1's graphics instance.
If it was me though particulary if I wanted enabled, visible, tab, click etc. I'd have a ShapedButton Control.

Related

How to clip the corner rectangle created by two scrollbar controls

Let's say you have a resizable window with child scrollbar controls, and the scrollbars come and go depending on whether the window contents are large enough to require scrolling.
When both scrollbars are present, a small rectangle is effectively created in the bottom right corner of the window, at their intersection. Is there a clean strategy for clipping that rectangle when drawing on the window, so that you don't paint on it?
I guess my current approach is to obtain the rectangles for each scrollbar, and if those rectangles are not null, then use the rectangles' locations to determine the rectangle that we want to clip. And then call ExcludeClipRect for that rectangle. I guess a similar approach could be used, except with GetSystemMetrics(SM_CXVSCROLL) and GetSystemMetrics(SM_CYVSCROLL) to get the rectangle dimensions.
But is there a more accepted way of doing this, perhaps using some helpful clipping API functions? Thank you for any input.

Set dialog window's border color

The root question here is this: How do I set the color for the border around a window (more specifically, a dialog window)?
I have a dialog window which pops up with an alert. Due to the critical safety nature of the alert, there is a requirement that some parts of the window be red, including the dialog's window-border. When I got this requirement in, I thought it was a good idea. Seems reasonable and simple enough.
The application uses X/motif for its graphics. I started by making other requested parts red, such as the acknowledgement button. Getting everything else done was simple enough by changing graphics contexts and color resources.
The dialog's border, however, has been a pain. There is an XmNborderColor resource, so I tried changing that. It didn't seem to work. Eventually, after trying to set it for different widgets (frame and it's ancestors), I did the following out of desparation:
Widget w = button;
for(int i = 0; i <= 20; i += 1)
{
printf("i = %d, w = %d\n", i, w);
if(w <= 0) break;
XtVaSetValues( w, XmNborderColor, border, NULL);
w = XtParent(w);
}
I did that to just set it on everything from the button to the root and everything between.
After doing some more research, I realized that I might need to be changing the window attributes instead, such as via XChangeWindowAttributes(display, window, mask, values). The structure for the values includes a border_pixel, which I'm assuming is the border color but can't find confirmation on that - documentation just says it's for setting "the border pixel." Fortunately, there is a convenience function for setting just the border pixel so that you do not need to pass an entire values structure; the convenience function that changes only the border pixel is XSetWindowBorder(display, window, border_pixel).
So I wanted to try that. I now have:
// control_area is the widget containing the other
XSetWindowBorder(XtDisplay(shell), window, border);
shell is set elsewhere with the following function:
Widget myClass :: createShell( Widget parent, string title )
{
while( !XtIsApplicationShell(parent) )
{
parent = XtParent( parent );
}
shell = XtVaCreatePopupShell( name, xmDialogShellWidgetClass, parent,
XtNvisual, visual, // visual, colormap, depth are class member variables
XtNcolormap, colormap,
XtNdepth, depth,
NULL );
XtVaSetValues( shell,
XmNmwmDecorations, MWM_DECOR_BORDER,
XtNtitle, const_cast<char*> (title.c_str()),
XmNmwmFunctions, NO_FUNCTIONS,
XmNresizePolicy, XmRESIZE_NONE,
NULL );
return shell;
}
From another place in the code, it looks like window might be a reference to the root window - maybe that's the problem?
I am surprised by the lack of information about this and by how difficult it has been to find a direct answer.
How do I set the border color? If I should be using XSetWindowBorder(), what am I doing wrong? If it's because my window variable might not be referencing the correct window, how do I get the a reference to the correct window knowing the shell and contained widgets (maybe I should make a separate question out of this one if this question doesn't get traction)?
The colour of the border is most likely controlled by your window manager unless you are running without a window manager. You need to override the default colour for that specific window in your ~/.Xdefaults file. Something like:
[title]*bordercolor: red
Where [title] is the same as the string you pass to createShell().

MFC selection of a user drawn rectangle on picture control

I'm trying to create an interface that allows the user to draw a rectangle over a picture control box. I have a picture control class and used CRectTracker to allow the user to draw a rectangle. I want the user to also be able to select a previously drawn rectangle but I don't know how to handle the selection of a drawn rectangle.
I want to be able to select the rectangle and also add resize handlers on it.
Here is my code for drawing the rect.
void PictureCtrl::OnLButtonDown(UINT nFlags, CPoint point)
{
// If mouse click is outside of rectangle
if(m_drawRect.m_tracker.HitTest(point) < 0 ) {
if(m_drawRect.m_tracker.TrackRubberBand(this, point, TRUE)) {
CDC* pDC = GetDC();
m_drawRect.m_tracker.m_nStyle &= CRectTracker::resizeInside;
// Paint transparent rectangle
pDC->SelectStockObject(NULL_BRUSH);
pDC->Rectangle(m_drawRect.m_tracker.m_rect);
ReleaseDC(pDC);
}
}
CStatic::OnLButtonDown(nFlags, point);
}
Any help would be appreciated. Thank you.
You will need to store the coordinates of the rectangle in your class (also save/load) and perform a HitTest during mouse-down.
To implement the resize handles, you will need a boolean to denote that the rectangle is selected (set boolean to FALSE if the click is not on the rectangle) and draw grab handles during paint if the boolean is TRUE; if the mouse moves over the grab handles, change the mouse-cursor, perform the resize during mouse-down and mouse-up in this case.
It's all quite complicated and gets more so if you have more than just one rectangle!
Here is a DrawCLI MSDN example which does all of that with rectangles, rounded rectangles, ellipses, lines and polylines plus support for OLE -- maybe this will help, it's probably easier to delete classes/functions from DrawCLI before it's in a state to merge with your application...

drawing inside a qt windows

I'd like to draw a color "frame" within a QT window. So, I have
setFixedSize(WIDTH, HEIGHT);
and I'd like to draw, say, a red (filled) border within width and height. Could anyone help me out?
Depends on a couple of things:
Is it a border around an existing widget? If it's just a border around an existing widget don't go down the route of painting it yourself, it's much simpler to use Stylesheets than draw it.
If of course you need a custom or very specific style, then you're best off drawing it using the Painting System. I'd strongly suggest do it using stylesheets unless you do need specifics. The paint system can be a bit unwieldy for just adding a border to a widget.

Creating a ruler bar in MFC

What's the best way to go about creating a vertical and horizontal ruler bars in an SDI app? Would you make it part of the frame or the view? Derive it from CControlBar, or is there a better method?
The vertical ruler must also be docked to a pane and not the frame.
To make it a little clearer as to what I'm after, imagine the vertical ruler in the Dialog Editor in Visual Studio (MFC only). It gets repositioned whenever the tree view is resized.
I would not use control bars. I have no good reason other then (IMOHO) are difficult to get to do what you want - if what you want if something other than a docking toolbar.
I would just draw them directly on the View window using GDI calls.
I guess I might think about making each ruler its own window, and draw the rulers on their own window. I would then create these two CWnd derived classes in the view and position as child windows. This is good if you want to interact with the mouse on these rulers (easier to sort out what messages are for the rulers).
I ended up deriving the ruler from CWnd as you suggested and skipping the control bar route. This code works in either case:
m_wndSplitter.CreateStatic(this, 1, 3);
m_wndLeftPane.Create(&m_wndSplitter,WS_CHILD|WS_VISIBLE,m_wndSplitter.IdFromRowCol(0, 0));
m_ruler.Create(&m_wndSplitter,WS_CHILD|WS_VISIBLE,m_wndSplitter.IdFromRowCol(0, 1));
m_wndSplitter.CreateView(0, 2, pContext->m_pNewViewClass, CSize(300, 0), pContext);
SetActiveView((CScrollView*)m_wndSplitter.GetDlgItem(m_wndSplitter.IdFromRowCol(0, 2)));