I have done an application with g++ using pure winapi, but every control looks very old. How can I use the new nice themes 7 and Vista offer? Everything I have read so far says that I must include an XML file saying explicitly that I want those themes, but I don't think that is possible with g++ . So, what should I do?
You do need to include a manifest to your project.
This is just a simple xml file that you add to your project as if it were a .cpp or .h file.
It will enable the nice visual styles, but you're not there yet!
The font is still the ms shell dlg which is not all that amazing.
To "extract" the standard font, you use the GetStockObject function with the DEFAULT_GUI_FONT flag
HFONT font = (HFONT) GetStockObject(DEFAULT_GUI_FONT);
To calculate the new dialog units for this font you can use this little snippet.
LONG units = GetDialogBaseUnits();
HDC hdc = GetDC(NULL);
SIZE size;
TEXTMETRIC tm;
HFONT font = (HFONT) GetStockObject(DEFAULT_GUI_FONT);
SelectObject(dc,font);
GetTextMetrics(dc,&tm);
GetTextExtentPoint32(hdc,"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",52,&size);
float avgWidth = (size.cx/26+1)/2;
float avgHeight = (WORD)tm.tmHeight;
float dialogUnitWidth = 2*(avgWidth/LOWORD(units));
float dialogUnitHeight = 2*(avgHeight/HIWORD(units));
dialogUnitWidth and dialogUnitHeight now contain the dialog units in pixels.
See this article for more information.
I don't know g++. But if the result of this environment/language you get is a simple EXE and the controls that are used are standard Windows controls adding a manifest to the exe will do the job.
The easiest way is to create a valid manifest with the complete Name of the exe and add .manifest to the Name. (i.e. foo.exe.manifest)
Related
I'm maintaining an application using Borland C++ Builder 6 running on Windows 7.
The application is incorrectly drawing text using font Courier New because each letter is being slighty cut off. The issue is when calling the method GetTextMetrics because it is filling the TEXTMETICS struct with differing tmAveCharWidth and tmMaxCharWidth values. The application then uses tmAveCharWidth to calculate character width with is wrong because that value it can be less than tmMaxCharWidth. That issue I will be fixing.
I courious why GetTextMetrics is returning differing tmAveCharWidth and tmMaxCharWidth values for Courier New? My understanding was that Courier New is a monospaced font and that tmAveCharWidth and tmMaxCharWidth should be the same. I tested with other monospaced fonts that that assumption is correct.
This is the section of code with the issue:
hFont = CreateFontIndirect(&lpInstData->lf);
hDC = GetDC(hWnd);
hFontOld = SelectObject(hDC, hFont);
GetTextMetrics(hDC, &tm);
lpInstData->nCharHeight = tm.tmHeight;
lpInstData->nCharWidth = tm.tmAveCharWidth; <--- Should be using tmMaxCharWidth
Here is the code running when I selected size 12 Courier New.
Parameter passed to CreateFontIndirect
TEXTMETRICS structure returned from GetTextMetrics
I found this was indeed ClearType at work (thanks Deanna). Turning off ClearType corrects the display issue without changing any code, although I still need to correct how the application works with ClearType.
I also found the issue was not present on Windows XP because ClearType is turned off by default, whereas in Windows 7 (and Vista) it is turned on by default.
Alrighty, I promise this is the closest I'll ever get to a "code for me" question :) If this doesn't drum up any responses I'll bite the bullet and build an OTF parser to check for the existence of a CFF table.
This info is available in the Windows font preview ('TrueType outlines' vs 'PostScript outlines'), so presumably there's a WinAPI function to this effect, but damned if I can find it.
Thoughts anyone?
ps - It's not a dealbreaker if only installed fonts can be checked, but checking files would be preferable.
You can do this using the GetFontData function.
Create the font in question and select it into a DC, then call GetFontData to query the size of the CFF table. This will only succeed if the font has PostScript outlines.
DWORD dwSize = GetFontData(hdc, ' FFC', 0, nullptr, 0);
if (dwSize && dwSize != GDI_ERROR)
{
// has PostScript outlines
}
The OpenType spec says:
OpenType fonts containing CFF data should use the tag 'OTTO' as the sfnt version number.
So, if the first four bytes of the file spell "OTTO" it uses PostScript outlines. Could it be simpler!? Tested & working so far, but I'll probably use GetFontData in the end.
Your best bet indeed seems to be to directly read the font tables from the font file itself. This sample here will give to a head start, assuming you're already familiar with the font tables. If not, read the links in the Reference section at the bottom of the article.
The first 4 bytes of a OpenType file who has a CFF block are "OTTO".
I realize win32 toolbar icon questions are common here, but none are relevant to my particular problem (most concern image lists, or associating with a bitmap handle).
I am trying to associate a toolbar button with an icon resource within my application. Since I am adding it to a toolbar that already has default images using TB_ADDBITMAP (new, open, save, etc), I cannot use an image list, as the article on MSDN says here:
The TB_SETIMAGELIST message cannot be combined with TB_ADDBITMAP. It also cannot be used with toolbars created with CreateToolbarEx, which calls TB_ADDBITMAP internally. When you create a toolbar with CreateToolbarEx or use TB_ADDBITMAP to add images, the toolbar manages the image list internally. Attempting to modify it with TB_SETIMAGELIST has unpredictable consequences.
MSDN says I should be able to use a resource directly with TB_ADDBITMAP, under the TBADDBITMAP::nID field:
If hInst is NULL, set this member to the bitmap handle of the bitmap with the button images. Otherwise, set it to the resource identifier of the bitmap with the button images.
The VS2008 resource editor shows a single 16x16 icon resource with the id IDI_ARROWLEFT. (I had a screenshot, but since I do not have enough "reputation" to post images you'll have to take my word for it)
This is clearly a valid icon as the following code makes the icon appear on the titlebar of the main window:
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_ARROWLEFT));
The problem is the resource icon is not appearing on the toolbar button within the window. Below is the sample code that is loading the resource and applying it to the toolbar button:
void populateToolbarTest()
{
int index = -1;
TBADDBITMAP tbab;
TBBUTTON tbb;
ZeroMemory(&tbab, sizeof(TBADDBITMAP));
ZeroMemory(&tbb, sizeof(TBBUTTON));
SendMessage(hWndToolbar, TB_BUTTONSTRUCTSIZE, (WPARAM) sizeof(TBBUTTON), 0);
tbab.hInst = hInst;
tbab.nID = IDI_ARROWLEFT;
// SendMessage returns 0 when testing
index = SendMessage(hWndToolbar, TB_ADDBITMAP, 1, (LPARAM)&tbab);
if (index == -1) return;
tbb.iBitmap = index;
tbb.fsState = TBSTATE_ENABLED;
tbb.fsStyle = TBSTYLE_BUTTON;
// result is set to 1 when testing
LRESULT result = SendMessage(hWndToolbar, TB_ADDBUTTONS, 1, (LPARAM)&tbb);
}
This code successfully produces a button. However, there is no icon displayed, unlike with the defaults that I used in IDB_STD_SMALL_COLOR
I finally got it working. Turns out, it had nothing to do with the code.
Microsoft is EXTREMELY picky about the EXACT format of the image being referenced. It you use TB_ADDBITMAP with a custom image, it MUST be 256 colors, it MUST have the MS-Specific index format, and the only color I've gotten to register as transparent is black. I spent an hour in Photoshop messing with different formats and colors before figuring this out.
The clue was the CreateMappedBitmap function in the example on MSDN. The page on CreateMappedBitmap had this statement:
This function is fully supported only for images with color maps; that is, images with 256 or fewer colors.
What it doesn't mention is that this is true regardless of whether you use this function or not. I have tried each scenario with and without this helper function, as well as tried every other 256-color BMP index format. Some other formats managed to show up, but they were mangled.
Theoretically, you can use the CreateMappedBitmap COLORMAP to specify a transparency color other than black, but I'm not familiar enough with the "6 level RGB" format to know how to specify an exact color.
(ref: http://en.wikipedia.org/wiki/List_of_software_palettes#6_level_RGB)
Unless you're mixing custom icons with default ones, I would recommend sticking with TB_SETIMAGELIST. From what I've read, it's much more flexible (for example, it accepts more than 256 colors.)
(ref: Win32 Toolbars and 24bit Images)
I wrote an OPENCV project in VS2010 and the results were not the ones as I expected so I ran the debugger to see where is the problem. When I wanted to see the data inside the image loaded I didn't know how to do it so if I want to see the data inside my images what should I do?
It is pretty simple in matlab for seeing different channel of an image i.e.
a=imread('test.jpg');
p1 = a(:,:,1)
p2 = b(:,:,2)
.
.
In opencv I wrote the same thing but I don't know how to see all the element at once just like Matlab.
a= imread("test.jpg")
split(a,planes);
vector<Mat> T1;
T1 = planes[0];
// How can I see the data inside T1 when debugging the code ?
I think this is what you are looking for - it's a great Visual Studio add-on
https://bitbucket.org/sergiu/opencv-visualizers
Just download the installer, make sure VS is closed, run it, re-open VS and voila! Now, when you point to an OpenCV data structure, all kinds of nice info is showed.
Limitations: I saw some problems with multichannel images (it only shows the first channel) and it also has trouble displaying large matrices. If you want to see raw data in a big matrix, you can use the old good VS trick with debug variables: Stop at a breakpoint, go to Watch tab, and write there
((float*)myMat.data) ,10
Where float is the matrix type, myMat is your matrix, and 10 is the number of values you want to print. It will display the first 10 values at the memory location of myMat.data. If you do not correctly choose the data type, you'll see garbage. In my example, myMat is of type cv::Mat.
And never forget the power of visualizers:
imshow("Image", myMat);
If your data fits into an image. You can use the contrib module's colormap to enhance your visualizers.
I can't actually believe that nobody suggested Image Watch yet. It's the most amazing add-in ever. It shows you a view with all your Mat variables (images (gray and color), matrices) while debugging, there's useful stuff like zooming or contrast-stretching and you can even apply more complex functions directly in the plugin in real-time. It makes debugging of any kind of image operations a breeze and it's immensely helpful if you do calculations and linear algebra stuff with your cv::Mat matrices.
I recommend to use a NativeViewer extension. It actually displays the content of an image in a preview window, not only the properly formatted info.
If you don't want to use a plug-in or extension to Visual Studio, you can access the elements one by one in the debugging watch tab by typing this:
T1.data[T1.step.buf[0]*i + T1.step.buf[1]*j];
where i is the row you want to look at and j is the column.
after downloading imagewatch use the command in watch window
(imagesLoc._Myfirst)[0]
index of image in the vector
You can use the immediate window and the extenshion method like this one
/// <summary>
/// Displays image
/// </summary>
public static void Display (this Mat m, Rect rect = default, string windowName = "")
{
if (string.IsNullOrEmpty(windowName))
{
windowName = m.ToString();
}
var img = rect == default ? m : m.Crop(rect);
double coef = Math.Min(1600d / img.Width, 800d / img.Height);
Cv2.ImShow(windowName, img.Resize(new Size(coef * img.Width, (coef * img.Height) > 1 ? coef * img.Height : 1)));
Cv2.WaitKey();
}
Then you stop at a breakpoint and call yourImage.Display() in the immediate window.
If you can use CLion you can utilize the OpenCV Image Viewer plugin, which displays matrices while debugging just on click.
https://plugins.jetbrains.com/plugin/14371-opencv-image-viewer
Disclaimer: I'm an author of this plugin
I have a Custom control derived from wxControl,inside a dialog with a vertical sizer
wxBoxSizer *topSizer = new wxBoxSizer( wxVERTICAL );
Knob* newKnob = new Knob(panel,wxID_ANY,wxDefaultPosition,wxSize(40,40));
topSizer->Add(newKnob,0,wxALL|wxALIGN_CENTER);
panel->SetSizer(topSizer);
topSizer->Fit(panel);
//panel is a wxPanel inside the dialog
But for some reason ,the custom controls' size is set at (80,100).If i resize the dialog beyond that size its aligned to center as i specified.
EDIT:
Am using wx 2.8.9 on windows Vista with visual studio 2005.
What could be missing?
You didn't provide any information about the wxWidgets version or your platform / compiler, so I will answer for wxWidgets 2.8 and MSW.
The size you specify is not necessarily used for the control, since the best size for different platforms may well be different. Even on Windows the size will usually depend on the default GUI font. So there are various methods in wxWidgets that let windows specify their minimum, best or maximum size. If you have special requirements you may need to override some of them.
For your problem it looks like you want to have the control have a smaller size than the default best size of wxControl:
wxSize wxControl::DoGetBestSize() const
{
return wxSize(DEFAULT_ITEM_WIDTH, DEFAULT_ITEM_HEIGHT);
}
(taken from src/msw/control.cpp) with the values
#define DEFAULT_ITEM_WIDTH 100
#define DEFAULT_ITEM_HEIGHT 80
(taken from include/wx/msw/private.h).
If you override DoGetBestSize() to return your intended size it should work.
Edit:
You comment that you cannot override DoGetBestSize() since it is not virtual in wxControl. It is though, because it is introduced in wxWindow:
// get the size which best suits the window: for a control, it would be
// the minimal size which doesn't truncate the control, for a panel - the
// same size as it would have after a call to Fit()
virtual wxSize DoGetBestSize() const;
(taken from include/wx/window.h). wxWindow is a parent class of wxControl, so the method is indeed virtual and you can of course override it. Many controls do in fact, as a grep in the sources will show you.