How to fixed CMFCPropertyListCtrl's column width? - c++

I have customized the column width CMFCPropertyListCtrl by overriding the same class.
Code:
class CMyPropertyGridCtrl : public CMFCPropertyGridCtrl
{
public:
void SetFirstColumnWidth(int width)
{
m_nLeftColumnWidth = width;
AdjustLayout();
}
};
And in OnSize() method of the class where pChannelListCtrl is declare as data member, I have called this method.
I want to fixed second column with size 50.
Code:
int iWidth = pChannelListCtrl.GetLeftColumnWidth();
pChannelListCtrl.SetFirstColumnWidth(iWidth + (iWidth - 50));
Here, its display as expected.(Second column with size 50).
Problem:
I want to keep the second column size fixed. But, here its resizable.
Can you please guide me, how to restrict the column resize.
Thanks,
Abdula

Override CMFCPropertyGridCtrl::SetLeftColumnWidth.
The header control for the grid is accessed with CMFCPropertyGridCtrl::GetHeaderCtrl()
Optionally, you can disable the header control to prevent resizing GetHeaderCtrl().EnableWindow(FALSE);
class CMyPropertyGridCtrl : public CMFCPropertyGridCtrl
{
public:
CMyPropertyGridCtrl()
{
m_nLeftColumnWidth = 50;
}
void make_fixed_header()
{
HDITEM hdItem = { 0 };
hdItem.mask = HDI_FORMAT;
GetHeaderCtrl().GetItem(0, &hdItem);
hdItem.fmt |= HDF_FIXEDWIDTH;
GetHeaderCtrl().SetItem(0, &hdItem);
}
void SetLeftColumnWidth(int cx)
{
m_nLeftColumnWidth = cx;
AdjustLayout();
}
void OnSize(UINT f, int cx, int cy)
{
EndEditItem();
if (cx > 50)
m_nLeftColumnWidth = cx - 50; //<- 2nd column will be 50 pixels
AdjustLayout();
}
DECLARE_MESSAGE_MAP()
};
BEGIN_MESSAGE_MAP(CMyPropertyGridCtrl, CMFCPropertyGridCtrl)
ON_WM_SIZE()
END_MESSAGE_MAP()
Use HDF_FIXEDWIDTH to fix the column for header control. From parent window call these functions after the control is created:
grid.SetLeftColumnWidth(50);
grid.make_fixed_header();
CMyPropertyGridCtrl::SetLeftColumnWidth will not detect when column is resized by the user. Override CMyPropertyGridCtrl::OnHeaderItemChanged in order to detect changes requested by user.

Related

Get rectangle that was drawn earlier with Rectangle() function

So I created a rectangle with Rectangle() function. When you are creating buttons, textboxes, you give them a certain number to access it later. Can I do the same with painted things?
P.S.: I need to create a rectangle and move it to another location
void SpawnRectangle(HDC hdc, int size, int amount)
{
int Offset = size / 2;
for (int i = 0; i < amount; ++i)
{
int LocationX = rand() % 1300 + 50;
int LocationY = rand() % 600 + 50;
Rectangle(hdc, LocationX - Offset, LocationY - Offset, LocationX + Offset, LocationY + Offset);
}
}
The Rectangle method (https://learn.microsoft.com/en-us/windows/desktop/api/wingdi/nf-wingdi-rectangle) draws a rectangle on the screen. It does not create a struct or class that defines the rectangle; it is literally the command to draw.
If you want to define a rectangle that you can use in other methods, FillRect, FrameRect, etc., then you want the RECT struct. This is a structure that you can create and store for later use, modify, and pass into other drawing methods.

Android Studio - Support Multiple Screens

I'm trying to support multiple screen sizes in my app... I added this to my Manifest.xml:
`<supports-screens
android:normalScreens="true"
android:smallScreens="true"
android:largeScreens="true"
android:xlargeScreens="true"
android:anyDensity="true"/>`
I also added different layout sizes and densities:
layout-small
layout-large
layout-normal
layout-xlarge
drawable-ldpi
drawable-hdpi
drawable-mdpi
drawable-xhpi
My layout-normal is currently set on Nexus 4: Image here
Now it's set on Nexus One: Image here
How can I set the elements to scale automatically?
Is there any other way to scale the elements automatically without setting their height and width to wrap_content or match_parent?
of course you can do it programmatically
example:
I defined Simple Object ImageSize like this:
public class ImageSize {
private float width;
private float height;
public float getWidth() {
return width;
}
public void setWidth(float width) {
this.width = width;
}
public float getHeight() {
return height;
}
public void setHeight(float height) {
this.height = height;
}
}
then I created a layout which contains Image(another layout) in it
final LinearLayout sellCarImage = (LinearLayout) findViewById(R.id.sellCarImage);
final RelativeLayout sellCarLayout = (RelativeLayout) findViewById(R.id.sellCarLayout);
then I've calculated width and height to scale view sizes based on image real size:
ImageSize img = new ImageSize();
img = getImageSize(R.drawable.indeximage5, MainActivity.this);
int sellCarWidth = sellCarLayout.getWidth();
int sellCarHeight = (int) ((sellCarWidth * img.getHeight()) / img.getWidth());
and programmatically set width and height:
RelativeLayout.LayoutParams sellCarImageIconParams = new RelativeLayout.LayoutParams(sellCarWidth, sellCarHeight);
//sellCarImageIconParams.setMargins(marg, 0, marg, 0);
sellCarImage.setLayoutParams(sellCarImageIconParams);
sellCarImage.setBackgroundResource(R.drawable.indeximage5);
here is getImageSize
public ImageSize getImageSize(int resource, Context ctx) {
ImageSize imageSize = new ImageSize();
BitmapFactory.Options dimensions = new BitmapFactory.Options();
dimensions.inJustDecodeBounds = true;
Bitmap mBitmap = BitmapFactory.decodeResource(ctx.getResources(), resource, dimensions);
imageSize.setHeight(dimensions.outHeight);
imageSize.setWidth(dimensions.outWidth);
return imageSize;
}
it's better to put them in:
sellCarLayout.post(new Runnable() {
#Override
public void run() {
//here
});
}
I hope it helps

QTableView issue with resizeEvent()

I have an object that inherits QTableView and overrides the resizeEvent() method to set the widths of the table columns to a percantage of the available space if the table as a whole is resized.
Code is as follows:
void DDUTableView::resizeEvent(QResizeEvent* ev)
{
int num_columns = NUM_ELEMENTS(COLUMN_WIDTHS);
if (num_columns > 0) {
int width = ev->size().width();
int used_width = 0;
// Set our widths to be a percentage of the available width
for (int i = 0; i < num_columns - 1; i++) {
int column_width = (width * COLUMN_WIDTHS[i]) / 100;
this->setColumnWidth(i, column_width);
used_width += column_width;
}
// Set our last column to the remaining width
this->setColumnWidth(num_columns - 1, width - used_width);
}
// Call our base resizeEvent to handle the vertical resizing which
// we don't bother with here
QTableView::resizeEvent(ev);
}
This all works fine until the user manually resizes one of the columns and stretches it beyond the viewport (bringing up the horizontal scrollbar). This then triggers my resizeEvent() call which resets the column widths to the percentage defaults.
I can overcome this issue by connecting to the sectionResized() signal on the table header and setting a timer running. If the resizeEvent() is called whilst the timer is active then I don't recalculate the table widths.
Code below:
connect(horizontalHeader(), SIGNAL(sectionResized(int, int, int)), this, SLOT(slotSectionResized(int, int, int)));
void DDUTableView::slotSectionResized(int /*logicalIndex*/, int /*oldSize*/, int /*newSize*/)
{
timer_->start(500);
}
void DDUTableView::resizeEvent(QResizeEvent* ev)
{
if (timer_->isActive()) {
return;
}
// etc
This works but is messy. Anyway the simple question is can I prevent the resizeEvent() from being called if the user manually adjusts the column headers beyond the scope of the viewport? Alternatively, if not, is it possible to identify in the resizeEvent() whether this particular situation has occurred without having to set timers and the like?
Checking if the scrollbar is visible worked for my scenario.
void DDUTableView::resizeEvent(QResizeEvent* ev)
{
if (!horizontalScrollBar()->isVisible()) {
int num_columns = NUM_ELEMENTS(COLUMN_WIDTHS);
if (num_columns > 0) {
int width = ev->size().width();
int used_width = 0;
// Set our widths to be a percentage of the available width
for (int i = 0; i < num_columns - 1; i++) {
int column_width = (width * COLUMN_WIDTHS[i]) / 100;
this->setColumnWidth(i, column_width);
used_width += column_width;
}
// Set our last column to the remaining width
this->setColumnWidth(num_columns - 1, width - used_width);
}
}
// Call our base resizeEvent to handle the vertical resizing which
// we don't bother with here
QTableView::resizeEvent(ev);
}

Animating an array of child class objects

I am trying to create a parent class "Shape" with child classes "Circle", "Triangle", "Rectangle". The parent class holds the x pos, y pos, and fill color or all the "shapes" and then each child class holds info specific to that shape. Would anyone mind looking over my code and see why im getting the error "Shapes does not have a member 'setRadius'" when trying to set the radius in the array of objects...
P.S. right now I only have the child class "Circle" until i get it working. Then I will add the other two classes.
Also, if anyone sees any other errors in my code, I would appreciate them being pointed out.
Thanks in advance
#include <allegro.h>
#include <cstdlib>
using namespace std;
#define scrX 640
#define scrY 400
#define WHITE makecol(255,255,255)
#define GRAY makecol(60,60,60)
#define BLUE makecol(17,30,214)
int random(int low, int high);
const int numCircles = random(1,50);
class Shape{
public:
Shape(){x = scrX / 2; y = scrY / 2; fill = WHITE;}
protected:
int x, y, fill;
};
class Circle : public Shape{
public:
Circle(){radius = 0;}
Circle(int r){radius = r;}
void setRadius(int r){radius = r;}
protected:
int radius;
};
int main()
{
// Program Initialization
allegro_init();
install_keyboard();
set_color_depth(32);
set_gfx_mode(GFX_AUTODETECT_WINDOWED, scrX, scrY, 0, 0);
// Create and clear the buffer for initial use
BITMAP *buffer = create_bitmap(scrX, scrY);
clear_to_color(buffer, GRAY);
// Set title and create label text in window
set_window_title("Bouncing Balls Ver 1.0");
textout_ex(buffer, font, "Bouncing Balls Ver 1.0", 10, 20, WHITE, GRAY);
// Draw a background box
rectfill(buffer, 50, 50, scrX-50, scrY-50, BLUE);
// Create circles
Shape **GCir;
GCir = new Shape *[numCircles];
for(int i=0;i<numCircles;i++){
GCir[i] = new Circle;
GCir[i]->setRadius(random(1,25)); // THIS IS THE ERROR
}
while(!key[KEY_ESC]){
blit(buffer, screen, 0, 0, 0, 0, scrX, scrY);
}
destroy_bitmap(buffer);
return 0;
}
END_OF_MAIN();
int random(int low, int high)
{
return rand() % (high - low) + low;
}
The type of GCir[i] is Shape* and the Shape class doesn't have a setRadius method, Circle does. So either call setRadius on the Circle object before assign it to GCir[i] or just construct the Circle with the proper radius: GCir[i] = new Circle(random(1,25));
hammer fix :
GCir[i]->setRadius(random(1,25));
should be changed to
((Circle*)GCir[i])->setRadius(random(1,25));
Deeper problems:
you need virtual destructor on BaseClass
a better way to do it is to take the radius in the Circle class constructor.
then either use Shape::draw() as a virtual function to specify shape drawing or implement Shape::getType() and use a switch case to determine drawing logic after proper casting.
Compiler said it. You have an array of Shapes on which you try to call setRadius which is only defined for Circles. You can only call shape methods without casting Shape poonter to circle.

Using inheritance to pass a non-static variable between classes

I'm researching UI's as a portfolio project and I ran into a little bit of trouble when it comes to inheritance. The problem I'm facing is this: I have two classes, R_GUI, in which I draw the form, and Button, where I draw the buttons. I want the Buttons to be positioned inside the FORM. I store the FORM position as form_x, and form_y. Here are my two classes:
class R_GUI
{
private:
bool get_pos_only_once;
bool move_form;
public:
int form_x, form_y;
int form_height, form_width;
int handle_bar_y;
inline void Form(int pos_x, int pos_y, int height, int width);
//inline void Button(int id, string ButtonText, int pos_x, int pos_y);
inline void Update_form(void);
inline void UPDATE(void);
inline ~R_GUI( );
inline R_GUI( )
{
d3dInit();
get_pos_only_once = false;
move_form = false;
form_x = 0;
form_y = 0;
handle_bar_y = 40;
}
};
and the Button class:
class Button: public R_GUI
{
private:
int b_form_x, b_form_y;
int b_handle_y;
int button_width, button_height;
public:
inline void Draw(string ButtonText, int b_pos_x, int b_pos_y);
Button()
{
b_form_x = R_GUI::form_x;
b_form_y = R_GUI::form_y;
b_handle_y = 20;
button_width = 90;
button_height = 35;
}
~Button();
};
As you can see, I'm trying to give b_form_x the value of form_x (which is a variable from R_GUI). form_x has a value, given in Form( );:
inline void R_GUI::Form(int pos_x, int pos_y, int height, int width)
{
if(get_pos_only_once == false)
{
form_x = pos_x;
form_y = pos_y;
form_height = height;
form_width = width;
get_pos_only_once = true;
}
//Create the form outline
d3dLine(pos_x,pos_y,pos_x+width,pos_y,dbRGB(50,50,50));
d3dLine(pos_x,pos_y,pos_x,pos_y+height,dbRGB(50,50,50));
d3dLine(pos_x+width,pos_y,pos_x+width,pos_y+height,dbRGB(50,50,50));
d3dLine(pos_x,pos_y+height,pos_x+width,pos_y+height,dbRGB(50,50,50));
//Create the handle bar
d3dLine(pos_x,pos_y+handle_bar_y,pos_x+width,pos_y+handle_bar_y,dbRGB(50,50,50));
//Fill the Handlebar;
d3dBox(pos_x,pos_y,pos_x+width,pos_y+handle_bar_y,dbRGB(3,3,3),dbRGB(3,3,3),dbRGB(3,3,3),dbRGB(3,3,3));
}
Yet, when I update the Form's Position, R_GUI::form_x value doesn't change. Any idea what I am doing wrong?
You don't want to have a second variable in your subclass (b_form_x). Eliminate it entirely. Instead, you want to use this->form_x, which in the Button will be inherited from R_GUI. The same applies for b_form_y.
this refers to the current instance of an object, and contains not only your local member variables but also any member variables inherited from classes all the way up the hierarchy as well.