I'm trying to show some images into my form. I've looked around a bit and tried some ways, but nothing works.
Here's my two attemps:
Added a picture control to my dialog;
Changed its type to Bitmap;
Added/drawed a bmp into resources;
In the picture control property changed Image to the id of my resource
In this way in the resource editor I can see the image correctly loaded but at run-time I don't see nothing.
Attempt 2:
CImage imgImmagine;
switch( imgImmagine.Load( _T("img/forza.bmp") ) )
{
case S_OK:
m_stForza.SetBitmap( (HBITMAP)imgImmagine );
m_stForza.Invalidate();
break;
case E_FAIL:
AfxMessageBox( _T("Nessuna immagine trovata!") );
break;
};
This time I obviously don't see anything in the dialog editor, but neither at runtime.
Where am I doing wrong?
Apparently it was (as usual) a Visual Studio 2010 problem, after some random operations the images now load correctly.
Related
In a custom control, I custom-draw TListView items myself in the TListView.OnAdvancedCustomDrawItem event. This works well.
I have been experimenting with several Theme classes and parts. For instance, when I use:
HTHEME Theme = OpenThemeData(Handle, L"Explorer::ListView") ;
DrawThemeBackground (Theme, Sender->Canvas->Handle, LVP_LISTITEM, LISS_NORMAL, &ItemRect, NULL);
I get what is to be expected, per Theme explorer (do notice the borders around the item):
But, if I look at a proper VCL TListView object, similar items are painted without a border. I expected this control to use the same Theme class and part. Is that not the case? If so, what class/part should I use to mimic the behavior?
This is what I see (notice the borders in the custom control vs the absence of borders in the true TListView control just below it:
I'm actually getting a 'nicer' result with LVP_GROUPHEADER, but I'm still very curious about LVP_LISTITEM.
FYI, using LVP_GROUPHEADER instead of LVP_LISTITEM. It works well for this type control, so a nice alternative, but I'm still very curious as to why the real ListView control paints no borders using LVP_LISTITEM (I THINK).
Perhaps I should add that I still use old C++ Builder 2009 for this project. This is a low effort attempt to improve the control to give it a life beyond W10 (Especially W11 where current MENU / MENU_POPUPITEM choice is not kind on the eyes). PS. having more problems with TPopupMenu now .. but that's another topic I guess.
A simple code example (not same as in project but showing the border):
#include "uxtheme.h"
#include "Vsstyle.h"
// Project includes uxtheme.lib
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
HTHEME Theme = OpenThemeData(Handle, L"Explorer::ListView") ;
TRect ItemRect = Image1->ClientRect ;
DrawThemeBackground (Theme, Image1->Canvas->Handle, LVP_LISTITEM, LISS_NORMAL, (tagRECT*)&ItemRect, NULL);
CloseThemeData(Theme) ;
}
//---------------------------------------------------------------------------
I met this problem. I have a simple Win32 program which is like the boilerplate which I can get from selecting a "Win32 project" under Visual Studio 2010's "Template --> Visual C++".
I found all other Windows based program like Adobe Reader, Windows Explorer having the feature which is: you enlarging the main window to a new size and then select "Close" or "Exit" from File menu or system menu to close it, then you launch the program again, the main window would be of the size that you adjusted to last time. However that program I got from Visual Studio as the bootstrap does not have such feature.
I researched more on it but cannot find which setting in either WndClass or CreateWindow that I can tweak to make that happen. Does anyone know it, thank you for your help in advance.
The simplest way to do this is with the GetWindowPlacement() and SetWindowPlacement() functions. These manage the window size and state (minimized/maximized/restored) for you.
Call GetWindowPlacement() when you want to record your window's current state:
WINDOWPLACEMENT wp = {0};
wp.length = sizeof(wp);
if (GetWindowPlacement(hWnd, &wp))
{
// save wp values somewhere...
}
You can then save the values of the WINDOWPLACEMENT structure somewhere in your program's configuration files - either in the registry or on disk.
To restore your window's information, load the saved values into the WINDOWPLACEMENT structure, then call the SetWindowPlacement() function:
if (values were previously saved)
{
WINDOWPLACEMENT wp = {0};
wp.length = sizeof(wp);
// load wp values from somewhere...
SetWindowPlacement(hWnd, &wp);
}
You will need to save the position (X, Y) and size (Height, Width) of the window yourself, and set those values when the program starts up again.
Depending on the nature of the program, you might set this in a configuration file, a registry key, or a database (among other options).
After moving and rearranging controls on a Winform when invoking a Build and/or Rebuild All command the following error message appears :
"An error occurred while processing this command. Could not load file
or assembly 'LoLock, Version=1.0.0.0, Culture=neutral,
PublicKeyToken=null' or one of its dependencies. The system cannot
find the file specified."
At that point all the controls disappear from the Designer and form the executing form as well. I've scoured the designer cs file and run diffs against a previous working version and cannot find anything amiss.
This has happened to me on several occasions and appears to be random.
Any clues ??
I've had the same problem...exactly...same error followed by the disappearance of most of the controls. The controls that are missing in the designer are my custom controls. The change I made before the error and the disappearance was to add a constructor to each of the controls derived class (i.e. my part of the control). So far, I've noted that the Control.Add(...) is missing for each of the hundred or so controls that have disappeared (from the automatically generated Form.designer.cs file). This is the one point that seems to differ from your situation if you are running a diff on the designer.cs file between pre and post failure. Mine definitely has missing Add()s.
So far, my solution is to manually add back the Add() methods to the generated file. However, it would obviously help if there was some way to get visual studio to see this problem and add the controls back automatically. However, I can't think of any way that VS could know, at this point, which controls to add to which parent control.
For example, before the error I had the following group box defined in my designer.cs file:
//
// groupBox10
//
this.groupBox10.Controls.Add(this.checkBox_FincaDescription_ForRent);
this.groupBox10.Controls.Add(this.checkBox_FincaDescription_ForSale);
this.groupBox10.Location = new System.Drawing.Point(883, 67);
this.groupBox10.Name = "groupBox10";
this.groupBox10.Size = new System.Drawing.Size(310, 76);
this.groupBox10.TabIndex = 9;
this.groupBox10.TabStop = false;
this.groupBox10.Text = "Property Type";
After the FAIL I have the following code which was generated as a result of either the error or simply the designers failure to manage my custom controls:
//
// groupBox10
//
this.groupBox10.Location = new System.Drawing.Point(883, 67);
this.groupBox10.Name = "groupBox10";
this.groupBox10.Size = new System.Drawing.Size(310, 76);
this.groupBox10.TabIndex = 9;
this.groupBox10.TabStop = false;
this.groupBox10.Text = "Property Type";
This is a massive FAIL for me as I have so many fields to manually correct (although luckily only a few group boxes and a good backup). I have read of so many people having this same problem from 2005 on, I can't believe it hasn't been addressed.
I also experienced this with a user control.
I received an exception for each control that had the Add method removed from the designer.
Surprisingly, I had a couple of panels, and the Add code for the children of those panels remained in tact.
I only had to implement Add for those panels and a few controls that were not in containers, which is fortunate because there were over 100 controls.
An error was introduced in the constructor of the user control, and I believe that this contributed to the chain of events resulting in the corrupt designer file.
I need to create a SDI form with a formview that has two tabs, which encapsulate multiple dialogs as the tab content. But the form has to have a colored background.
And things like these makes me hate programming.
First, I tried CTabControl, via resource editor, tried different things, but the undocumented behavior and the quirks with no answers led me into a roadblock.
After many hours of searching, I found that there is a control called property sheet, which is actually what I need.
Some more searching later, I found that property sheet can even be actually embedded onto CFormView like so: http://www.codeguru.com/Cpp/controls/propertysheet/article.php/c591
And that the dialog classes derived from CPropertyPage can be directly added as pages via AddPage method of CPropertySheet.
Great! Not quite so... Some of the controls didn't worked, and were not created, ran into weird asserts. Turns out the DS_CONTROL style was missing from the dialogs. Found it completely accidentaly on Link, no word about that on MSDN!!!! Property page must have: DS_3DLOOK | DS_CONTROL | WS_CHILD | WS_TABSTOP, and can have: DS_SHELLFONT | DS_LOCALEDIT | WS_CLIPCHILDREN styles! Not any other, which are created by default with resource editor. Sweet, super hidden information for software developers!
The quote in comments on that page: "OMG. That's where that behavior came from...
It turns out that the PlaySound API relied on that behavior when playing sounds on 64bit machines." by Larry Osterman, who as I understand works for Microsoft for 20 years, got me laughing out loud.
Anyway, fixed that, the dialog-controls(CPropertyPages) are created as expected now, and that part looks something remotely promising, but the next part with color is dead end again!
Normally you override WM_CTLCOLOR, check for control ID or hwnd and supply the necessary brush to set the color you need. Not quite so with CPropertySheet, the whole top row stays gray! For CTabCtrl it somehow works, for CPropertySheet it doesn't.
Why? Seems that the CPropertySheet is kinda embedded inside CTabControl or something, because if I override WM_ERASEBKGND, only the internal part changes the color.
Now it seems that there is a GetTabControl() method in the CPropertySheet, that returns the actual CTabCtrl* of the CPropertySheet. But since it's constructed internally, I can't find how to override it's WM_CTLCOLOR message processing.
There seems to be a way to subclass the windowproc, but after multiple tries I can't find any good source on how to do it. SubclassWindow doc on MSDN says: "The window must not already be attached to an MFC object when this function is called."?! What's that?
I tried creating a custom CCustomTabCtrl class based on CTabCtrl via MFC wizard, created an instance of it, called SubclassWindow from one of the CCustomPropertySheet handlers to override the internal CTabCtrl, but nothing works, mystical crashes deep inside MFC.
Tried setting WindowLong with GCL_HBRBACKGROUND for the internal CTabCtrl, nothing changed.
And worst of all, I can't find any sort of useful documentation or tutorials on the topic.
Most I can find is how to ownerdraw the tab control, but this is seriously wrong on so many ways, I want a standard control behavior minus background color, I don't want to support different color schemes, windows versions, IAccesible interfaces and all this stuff, and none of the ownerdraw samples I've seen can get even 10% of all the standard control behavior right. I have no illusion that I will create something better, I wont with the resources at hand.
I stumbled upon this thread, and I can't agree with the author more: http://arstechnica.com/civis/viewtopic.php?f=20&t=169886&sid=aad002424e80121e514548d428cf09c6 owner draw controls are undocumented PITA, that are impossible to do right, and there is NULL information on MSDN to help.
So is there anything I have missed or haven't tried yet? How to change the top strip background color of the CPropertySheet? Anyone?
Your only option is to ownerdraw the tab control. It's not that hard. Well, it is frustrating because MFC doesn't tell you how to make the necessary Win32 calls.
In your CPropertySheet-derived class, overwrite OnInitDialog() and add:
GetTabControl()->ModifyStyle(0,TCS_OWNERDRAWFIXED);
This puts your CPropertySheet-derived class in charge of drawing the tab control. Add a handler for WM_DRAWITEM (OnDrawItem) and change backgroundColor and textColor to match whatever colors you wanted. Code for OnDrawItem follows:
void CPropSht::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct)
{
if (ODT_TAB != lpDrawItemStruct->CtlType)
{
CPropertySheet::OnDrawItem(nIDCtl, lpDrawItemStruct);
return;
}
// prepare to draw the tab control
COLORREF backgroundColor = RGB(0,255,0);
COLORREF textColor = RGB(0,0,255);
CTabCtrl *c_Tab = GetTabControl();
// Get the current tab item text.
TCHAR buffer[256] = {0};
TC_ITEM tcItem;
tcItem.pszText = buffer;
tcItem.cchTextMax = 256;
tcItem.mask = TCIF_TEXT;
if (!c_Tab->GetItem(c_Tab->GetCurSel(), &tcItem )) return;
// draw it
CDC aDC;
aDC.Attach(lpDrawItemStruct->hDC);
int nSavedDC = aDC.SaveDC();
CBrush newBrush;
newBrush.CreateSolidBrush(backgroundColor);
aDC.SelectObject(&newBrush);
aDC.FillRect(&lpDrawItemStruct->rcItem, &newBrush);
aDC.SetBkMode(TRANSPARENT);
aDC.SetTextColor(textColor);
aDC.DrawText(tcItem.pszText, &lpDrawItemStruct->rcItem, DT_CENTER|DT_VCENTER|DT_SINGLELINE);
aDC.RestoreDC(nSavedDC);
aDC.Detach();
}
Thank you for this solution but...
The above solution works well with one tab, but when you have multiple tabs it seems rename the wrong tabs. I needed to change the if statement for GetItem to:
if (!c_Tab->GetItem(lpDrawItemStruct->itemID, &tcItem )) return;
Needed lpDrawItemStruct->itemID to get the tabs named correctly
I'm writing an application for a Pocket PC 2003 device. In it there is a dialog where various text information is shown. The information is separated so that each piece resides inside its own label, defined as LTEXT in the resource file.
Now my problem is that, at the moment, all text lables have the same font and style (normal or simple, i.e. not bold or italic); I want want one to be set in bold. I know that I can set the font to bold in the resource file, but that sets the style of all labels.
How does one achieve this? I've seen it be used in the Windows 'About' screen so I know it's possible. I've written the program in C++ using the Win32 API directly (except for certain dialogs where I've used the resource file) so I would appreciate if the answer was given in the same language and approach.
Thanks.
In the resource editor, edit the static text item, and change its control ID to something unique: IDC_BOLD for example.
In the DialogProc for the dialog boxes that is hosting the control, add a WM_CTLCOLORSTATIC handler:
case WM_CTLCOLORSTATIC:
HDC hdc;
HWND hwndCtl;
hwndCtl = (HWND) lParam;
hdc = (HDC) wParam;
if( GetWindowLong(hwndClt, GWL_ID ) == IDC_BOLD )
{
SetBkMode(hdc,TRANSPARENT);
SetTextColor(hdc,RGB(0xff,0,0)); // turn the text red for fun :)
SelectObject(hdc,hBoldFont); // but you want this...
return (INT_PTR)GetSysColorBrush(COLOR_BTNFACE);
//return 0L; // if visual themes are enabled (common controls 6) then 0 is better.
}
// default processing
return 0;
You are developing for Pocket PC 2003, I don't know what buttons styles are available. This Page refers of course to desktop XP. But, if the buttons in the dialogs are not flat grey 95esq buttons, then it might be more appropriate to return 0 as that will paint the text background correctly if the dialogs background is not plain grey.
Pre-visual styles a return of 0 causes the system to reset the DC so its important to know which return is appropriate.