CMFCToolbar and CMFCMenubar displaying wrong tooltips - menu

Question asked also on https://social.msdn.microsoft.com/Forums/vstudio/en-US/f64c99e5-f490-454f-951f-aee794e9506b/cmfctoolbar-and-cmfcmenubar-displaying-wrong-tooltips
I am using Visual Studio 2010, but I suspect the bug is still present on the 2013 version, as I compared the winfrm.cpp file and the OnToolTipText are exactly equal on the two files.
The bug is happening always at the 7th, 8th or 16th element.
Although separators count as elements for this counting, the tooltips do not appear over them.
Element can be a textual MENUITEM, a POPUP menu or toolbar button.
The string table defines are:
#define IDS_SEVEN 7
#define IDS_EIGHT 8
#define IDS_NINE 9
#define IDS_TEN 10
#define IDS_ELEVEN 11
#define IDS_TWELVE 12
#define IDS_THIRTEEN 13
#define IDS_FOURTEEN 14
#define IDS_FIFTEEN 15
#define IDS_SIXTEEN 16
and the STRINGTABLE contents are:
IDS_SEVEN "Seven"
IDS_EIGHT "Eight"
IDS_NINE "Nine"
IDS_TEN "Ten"
IDS_ELEVEN "Eleven"
IDS_TWELVE "Twelve"
IDS_THIRTEEN "Thirteen"
IDS_FOURTEEN "Fourteen"
IDS_FIFTEEN "Fifteen"
IDS_SIXTEEN "Sixteen"
So, when I hover with the mouse pointer the 7th, 8th or 16th element I get WRONGLY a tooltip displaying the string with that ID (Example:7th element displays "Seven").
It happens with all my toolbars and all my menus with a sufficient number of items, including in the toplevel horizontal menubar.
I discovered that the guilty function is:
BOOL CFrameWnd::OnToolTipText(UINT, NMHDR* pNMHDR, LRESULT* pResult)
as the nID local variable does not get the ABSOLUTE ID of the Command, but the POSITIONAL order of the button, starting with 1 instead of 0.
If I would move the strings IDs out of that range, whenever a user wants to add new strings, the Visual Studio Resource Editor would see that space free and use it, filling it again. And the problem would happen again. So, it is not a valid solution.
I could also define strings for all commands. But as we are maintaining four TFS branches at the same time and the change needs to go to all branches, this change would be potentially very dangerous when doing merges after.
So, please what solution do you recommend to not display those stupid tooltips?
UPDATE: I didn't copy the string table exactly as it was. It was like this:
IDS_SEVEN "Seven\nSeven"
IDS_EIGHT "Eight\nEight"
IDS_NINE "Nine"
IDS_TEN "Ten"
IDS_ELEVEN "Eleven"
IDS_TWELVE "Twelve"
IDS_THIRTEEN "Thirteen"
IDS_FOURTEEN "Fourteen"
IDS_FIFTEEN "Fifteen"
IDS_SIXTEEN "Sixteen\nSixteen"

In the update I put a stringtable more similar to the one I had. I had not noticed before a common feature of 7, 8 and 16 th strings: they all had '\n' characters in their contents.
I think nobody will create a menu with more than 512 menuitems nor toolbars with more than 512 buttons, so my solution was to change all strings containing '\n' characters with an ID below 512 to numbers above 512.
And it works.

Related

MFC Accelerator resource ID conflicts?

Someone change the numerical value of one of the accelerator in the resource.h file and because of that the accelerator stopped working.
(old value that was working)
#define IDR_DELETE_FROM_ACCELERATOR 32873
(new value that is not working)
#define IDR_DELETE_FROM_ACCELERATOR 22873
related code :
ON_COMMAND( IDR_DELETE_FROM_ACCELERATOR, OnDeleteFromAccelerator )
void CMyViewClass::OnDeleteFromAccelerator()
{
///....
}
In both cases, the numerical values are unique (no conflict).
From MSDN, It seems that both numerical values should be valid.
Am I reading/understanding this correctly?
I can simply renumber the value to the one that worked, but I would like to understand why it stopped working.
Thanks,
Max.
Read the TN020 paying more attention.
On the table it is stated:
ID_ commands 0x8000 through 0xDFFF
0x8000 in decimal is 32768.
22873 is lower than that.

How to generate a pin code in Symfony

I'm working right now on a symfony2 web app and I need to generate automatically and randomly pin-code composed by 6 alphanumeric characters example:
14gkf8
kfgh88
this code will be sent by mail to the use, that's how he will connect to the platform.
anyone have an idea how to make it or there is maybe a ready tool to do it ? thank you
You can generate random codes with the following code:
substr(bin2hex(openssl_random_pseudo_bytes(100)), 0, 6)
Online demo.
openssl_random_pseudo_bytes() will generate random binary data, bin2hex() will transform this binary data as hexadecimal data (e.g. 5c3aa…e55) and substr(…, 0, 6) will keep only the 6 first characters. Since hexadecimal uses values from 0 to 9 and a to f, there is 16 different characters available at each position, so it gives 16^6 = 16,777,216 possibilities (with 0 to 9 and a to z it's 36^6 = 2,176,782,336, only ± 130 times more). If the user doesn't need to type the key, you can use more characters, for example with 12 characters you have many more possibilities: 16^12 = 2,814×10¹⁴.
You can use uniqid() to generate a unique alphanumeric string

Increasing the number of suggests shown in omnibox

Is it in anyway possible to increase the number of suggests that your extension may show in the omnibox?
By default it looks like 5 rows is the limit. I've read about a command line switch to change the number of rows (--omnibox-popup-count) but I am really interested in dynamically being able to set this in my extension.
5 rows isn't really enough for the information my extension want to show.
[Update 2018 - thanx version365 & Aaron!]
» Not hardcoded anymore! chrome://flags/#omnibox-ui-max-autocomplete-matches . Credit goes to #version365 answering below: http://stackoverflow.com/a/47806290/234309 « – Aaron Thoma
..[historical] detail: since the removal of --omnibox-popup-count flag (http://codereview.chromium.org/2013008) in May 2010 the number [was] hardcoded:
const size_t AutocompleteResult::kMaxMatches = 6;
a discussion two years later on the chromium-discuss mailing list about the 'Omnibox default configuration' "concluded"
"On lower performing machines generating more result would slow down the result display. The current number look like a good balance."
[which is not a very valid argument, considering the probably infinitesimal overhead retrieving more items than the hard-wired number]
why the heck is there no chromium fork that removes stupid UX limitations like this (or the no tabbar in fullscreen mode)^^
Since there is no more --omnibox-popup-count flag; you can use another flag which is new.
chrome://flags/#omnibox-ui-max-autocomplete-matches lets you select a maximum of 12 rows.
In fact there is no more --omnibox-popup-count flag
http://code.google.com/p/chromium/issues/detail?id=40083
So I think there is no way to enlarge the omnibox.

Unicode strings not showing in Win32 ComboBoxEx

I am creating a WC_COMBOBOXEX on Windows Vista and adding strings to it, but they don't show up in the control. The same strings show up fine if I use the old WC_COMBOBOX with CB_ADDSTRING.
I am calling InitCommonControlsEx with ICC_USEREX_CLASSES and creating the comboboxex using CreateWindowEx with style WS_CHILD|WS_CLIPSIBLINGS|CBS_SIMPLE|CBS_SORT|CBS_HASSTRINGS (no extended styles). I am adding the strings using
COMBOBOXEXITEM cbem = {0};
cbem.mask = CBEIF_TEXT;
cbem.iItem = -1;
cbem.pszText = L"hello";
SendMessage(hWnd_, CBEM_INSERTITEM, 0, TOLPARAM(&cbem));
The combobox comes up empty but when I move the cursor up and down in the editcontrol/listbox, I see funny block characters sometimes.
Eventually, I want to add it as a CBS_DROPDOWNLIST to a rebar control but I read somewhere that comboboxex works a lot better in there than the old combobox.
Thanks.
From MSDN:
ComboBoxEx controls support only the following ComboBox styles:
CBS_SIMPLE
CBS_DROPDOWN
CBS_DROPDOWNLIST
WS_CHILD
So CBS_SORT and CBS_HASSTRINGS may be messing up the style bits.
Does it help if you send CBEM_SETUNICODEFORMAT?

Custom field in file version in C++ project

Hi
is there a way to create a custom field in the file version for a C++ project. So that we can see these fields along with file version, company name, etc. I would like to create fields like
revision = 1000
Customization = OEM1
.
Thanks
John
You can add extra fields to the version information in your .rc file. You can't add numeric fields, but you can add localized string fields. I have never tried to do this with the GUI, but I know you can do it by changing the file directly.
In Visual C++, right click on your .rc file and click "View Code." Somewhere in there, you will find a section that starts with:
BLOCK "StringFileInfo"
That block probably only has one sub-block:
BLOCK "0409904b0"
That number is the numeric version of the locale descriptor for en_us. This block contains several VALUE entries such as:
VALUE "FileVersion", "1, 0, 0, 0"
VALUE "OriginalFilename", "MyProjectName"
You can add any field you want to this section and it will show up on the version tab of the properties dialog for the executable.
If you need to be able to read these values at runtime, you can use GetFileVersionInfo like this:
wchar_t myModululeName[MAX_PATH];
GetModuleFileName(NULL,myModuleName,MAX_PATH);
DWORD dummy;
DWORD versionSize=GetFileVersionInfoSize(myModuleName,&dummy);
//I don't remember why I added extra space to these
void * versionInfo=malloc(versionSize+10);
GetFileVersionInfo(myModuleName,0,versionSize+1,versionInfo);
//This part is optional
//The VS_FIXEDFILEINFO contains information from the non-localized parts of
//the "StringFileInfo" block in the .rc file
VS_FIXEDFILEINFO * fixedFileInfo;
UINT fixedFileSize;
VerQueryValue(versionInfo,L"\\",(void **)(&fixedFileInfo),&fixedFileSize);
//This will retrieve the local codes that are defined in the StringFileInfo block
WORD * translationTable;
UINT translationSize;
VerQueryValue(verionInfo,L"\\VarFileInfo\\Translation",(void **)(&translationTable),&translationTableSize);
//This always uses the first locale, you could examine translationTable
//if you need to for other codes
wchar_t mySpecialQuery[128];
sprintf_s(mySpecialQuery,L"\\StringFileInfo\\%04x%04x\\MySpecialVersionInfo",translationTable[0],translationTable[1]);
wchar_t * mySpecialValue;
UINT mySpecialValueSize;
VerQueryValue(versionInfo,mySpecialQuery,(void **)(&mySpecialValue),&mySpecialValueSize);
//you can now do whatever you need to do with mySpecialValue, including using _wtoi()
//and query for more values
free(versionInfo);

Resources