G'day folks, I'm attempting to write out a CSV file (don't ask) in a format that can be read by Excel (also don't ask) across Locales. Now, this is fine, I can format the numeric values correctly and then separate them using the locale's list separator. However, it seems that Excel only ever uses the System Locale list separator. That is, if some user overrides their separator (again, don't ask) to ',', Excel doesn't use that, but the original default setting for the locale (in the Italian locale, ';'). Is this behaviour expected? Sensible? A pain in the #$%? Thanks. ------------------------ Derek Waters derek@lj-oz.com
Derek Waters
Posts
-
Excel Locale Issue -
Enable/Disable Toolbar *Buttons* :: MFCAaah, that old chestnut! It really depends on what the toolbar button does. If the operation of the button could apply to more than one view type (for example, the program I'm working on has ten doc/view types, and some buttons apply to all, while others apply to only one) then it probably makes more sense to put it in MainFrame. If the button only really applies to one view type, it's probably going to be easier to update in the view, otherwise you're going to need to do something like:
void CMainFrame::MyUpdateHandle(CCMdUI *pCmdUI)
{
pCmdUI->Enable(FALSE);
CFrameWnd *vpFrame = GetActiveFrame();
if (vpFrame != NULL)
{
CView *vpView = vpFrame->GetActiveView();
if (vpView != NULL)
{
if (vpView->IsKindOf(RUNTIME_CLASS(CMyButtonView)))
{
CMyButtonView *vpMyView = static_castvpView;
if (vpMyView->ShouldIEnableTheButton())
{
pCmdUI->Enable(TRUE);
}
}
}
}
}Whew! As opposed to:
CMyButtonView::OnUpdateButton(CCmdUI *pCmdUI)
{
pCmdUI->Enable(ShouldIEnableTheButton());
}So, all in all, it's really a style/ease of programming kind of question. I'll leave that decision up to you... Hope this helps. ------------------------ Derek Waters derek@lj-oz.com
-
Enable/Disable Toolbar *Buttons* :: MFCWell, you can put your command handler anywhere that message are received. The best place to put them in this case would probably be the CFrameWnd-derived class where you create the toolbar. The same class would also have a handler for the menu item. For example, if the menu item is ID_ALLOW_BUTTON and the button itself is ID_MY_BUTTON: In the header:
bool m_bButtonAllowed;
afx_msg void OnAllowButtonMenu();
afx_msg void OnUpdateMyButton(CCmdUI *pCmdUI);
afx_msg void OnMyButton();In your constructor:
m_bButtonAllowed = false;
In the message map:
ON_COMMAND(ID_ALLOW_BUTTON, OnAllowButtonMenu)
ON_UPDATE_COMMAND_UI(ID_MY_BUTTON, OnUpdateMyButton)
ON_COMMAND(ID_MY_BUTTON, OnMyButton)Then:
CMainFrame::OnAllowButtonMenu()
{
m_bButtonAllowed = true;
}CMainFrame::OnUpdateMyButton(CCmdUI *pCmdUI)
{
pCmdUI->Enable(m_bButtonAllowed ? 1 : 0);
}CMainFrame::OnMyButton()
{
AfxMessageBox("Got me!");
}Hope this helps. ------------------------ Derek Waters derek@lj-oz.com
-
Problem with LIKE from MFCWhat does strSql contain after the format statement? I suspect from the example you gave that you'll be missing a percentage and quote sign. This is because the two characters "%'" will be removed from your string. To get a '%' character in a string you need to put two of them (%%):
strSql.Format("SELECT COUNT([TblCatalogList].[CatalogId]) FROM [TblCatalogList] WHERE [TblCatalogList].[PcBoard] LIKE '%s%%'",strBoard);
Hope this helps. ------------------------ Derek Waters derek@lj-oz.com
-
Enable/Disable Toolbar *Buttons* :: MFCWhen you create each button in the toolbar, it should have an associated command ID. These IDs are passed in as an array in the CToolBar::SetButtons() command. If you create a toolbar in the resource editor (this is from memory, I don't normally do it this way) I think you just select one of the buttons on your toolbar and bring up the properties, then add a command ID there. Anyway, this ID is the command ID used in the ON_UPDATE_COMMAND_UI update handler (ie you have one handler per toolbar button, not for the toolbar as a whole). If you have a range of toolbar buttons and you don't want to write code for all of them, you can also use ON_UPDATE_COMMAND_UI_RANGE. So, in summary, each Update Command handler should apply to a single toolbar button. ------------------------ Derek Waters derek@lj-oz.com
-
Looking at arrays with DebuggerI don't know about the error in OMF type information thing, but the second value is correct. When you declare CPoint coord[80], coord actually becomes a (CPoint *) pointing to a block of 80 CPoint values. Therefore, when you view coord, it will display the address of the start of this memory block. There are two ways to look at the values in this array: Add coord[0] or coord[53] to the Watch window to look at individual elements of this array, or copy 0x0066f288 to the Memory Debug window and look at the raw memory bytes (not so easy!). Hope this helps. ------------------------ Derek Waters derek@lj-oz.com
-
Date Time PickerWell, assuming that you're using some COM-based technology to access your Access DB (and I would imagine it'd be pretty tough otherwise!) then COleDateTime can easily be converted to a VARIANT of VT_DATE type using COleVariant. This will be exactly the format that Access's automation interface will be expecting. ------------------------ Derek Waters derek@lj-oz.com
-
Date Time PickerHi, Your problem is that the MFC CTime class actually uses the mktime() call internally. If you look at the definition of mktime() you'll see that it uses a time_t, which is a floating point value representing the number of seconds since, you guessed it, Jan 1 1970. The problem here is the fact that you're mapping your control to a CTime value. Open the ClassWizard and delete the mapped variable. Add it again, but make sure you select COleDateTime from the Variable Type combo. This should give you a much larger range of values. Hope this helps. ------------------------ Derek Waters derek@lj-oz.com
-
Template/class link errorYou can't declare the implementation of template classes in your .cpp files. Try moving all the functions inline into your template classes .h file and see how you go. Hope this helps. ------------------------ Derek Waters derek@lj-oz.com
-
I need your help on this guys...- If you don't need to modify the char array, you can simply cast a CString to an LPCTSTR (long? pointer const TCHAR string):
LPCTSTR apszBuffer = (LPCTSTR)m_MyCstring;
If you need to modify the buffer, you need to use GetBuffer and ReleaseBuffer:
LPTSTR apszMyBuffer = m_MyCString.GetBuffer(m_MyCString.GetLength());
// Do something with apszMyBuffer, changing its length to 25
m_MyCString.ReleaseBuffer(25);- Use atoi, atof (or _ttoi for wide-char compatibility):
int viValue = atoi("25478");
float vfValue = atof("123.456");- Use CString::Mid():
CString vstrBit = m_MyCString.Mid(0, 2); // First two chars
CString vstrAnother = m_MyCString.Mid(5, 4); // Chars 5-8Hope this helps. ------------------------ Derek Waters derek@lj-oz.com
-
Automatically Minimizing WindowYep:
CMyDialog::OnTestBtn()
{
ShowWindow(SW_MINIMIZE);
}Hope this helps. ------------------------ Derek Waters derek@lj-oz.com
-
static member funcs/variablesIn your CPP file, you don't need the static on the front, and I think you've got the *s in the wrong place:
C2DPoint **CTracker::m_aCentroids = NULL;
double ***CTracker::m_aCentroidDirs = NULL;
UINT *CTracker::m_aNumPoints = NULL;Hope this helps.
Derek Waters
derek@lj-oz.com -
DLL mandatory with EXEYep, Unicode is an issue. However, the DLLs are actually named differently. If you look in C:\winnt\system32 (or equivalent) on the machine where you installed VC++, you'll find that along with MFC42.DLL there is also a file called MFC42U.DLL, the Unicode version. Similarly for all the VC++ related DLLs. Basically, when you build a Unicode version of your program, it it linked against the Unicode DLLs. Therefore, if you try to run a Unicode program on a non-Unicode system, it will fail. Anyway, what I'm getting at is that if you build a non-Unicode application, you can update MFC42.DLL without a problem, since it is non-unicode. As for the redistributable files, in fact, the recommended way is to copy them from your VC++ CD. Do a search for "Redistributable Files" in MSDN and you'll find more info. The list of files allowed for redistribution can be found in the Program Files / MS Visual Studio folder and is called redist.txt. Hope this helps. ------------------------ Derek Waters derek@lj-oz.com
-
DLL mandatory with EXEFrederic Filiatrault wrote: 1) How can I know which one of those DLL other users have Well, the simple answer is that you need to find the corresponding DLL on their system. Usually they will be in the C:\Winnt\System32\ or C:\windows\system\ folder. 2) I have WinXP, what happen if I want to give my EXE to someone with a older OS version like Win98 ? This one is down to your installer. As long as you are not relying on newer functions in these DLLs (MSDN help tells you which versions of DLLs each API call resides in) then you should be OK. Your program's installer should, in theory, include the versions of each DLL that your program relies on, and should check to see whether the user's version of the DLL is newer. If the user's current version is older, then you can copy (and register, if necessary) your copy of the DLL. You can also find out what versions of Windows DLLs are installed by what products by looking at the Microsoft DLL database at: http://support.microsoft.com/servicedesks/fileversion/dllinfo.asp?fr=0&sd=msdn Hope this helps. ------------------------ Derek Waters derek@lj-oz.com
-
Code Segment QuestionThe easiest way to find out would be to use the sizeof operator:
int viSize1 = sizeof(ISInst1);
int viSize2 = sizeof(InstPtr);------------------------ Derek Waters derek@lj-oz.com
-
DLL mandatory with EXEYou can find out what DLLs your program requires by running the Dependency Walker (depends.exe) that comes with VC++. The difference between debug and release builds is that debug builds use MFC42D.DLL and MSVCRTD.DLL instead of MFC42.DLL and MSVCRT.DLL (no D's). The debug versions of these are not redistributable, so you should only distribute Release versions of your software. As described in the earlier post, linking statically removes the hassle of having to distribute these DLLs with your program, however, you may need others that depends.exe will show you. ------------------------ Derek Waters derek@lj-oz.com
-
How to use function "OnDeleteitem(NMHDR* pNMHDR, LRESULT* pResult) " on ctreectrl?Huh? Do you mean how to add a DeleteItem notification handler, or what to do when you get it? To add the notification, you need to add
afx_msg void OnDeleteTreeItem(NMHDR *pNMHDR, LRESULT *pResult);
to your header, then add:
ON_NOTIFY(TVN_DELETEITEM, IDC_MY_TREE_CTRL, OnDeleteTreeItem)
to your message map. Finally, add the handler to your .cpp file:
void CMyClass::OnDeleteTreeItem(NMHDR *pNMHDR, LRESULT *pResult)
{
NMTREEVIEW *pTreeNotify = (NMTREEVIEW *)pNMHDR;// Now pTreeNotify->itemOld.hItem is the HTREEITEM of the deleted tree item
}As to what you do in the handler, that's up to you... ------------------------ Derek Waters derek@lj-oz.com
-
Best method for creating a Wizard w/ VC++ and MFC?If you're using MFC, you might want to have a look at CPropertySheet and SetWizardMode. Basically you can maintain your dialog templates separately, and create a CPropertyPage-derived class for each one. Then you simply add each Page to your Sheet, SetWizardMode, and away you go. Much easier than rolling your own, methinks... Hope this helps. ------------------------ Derek Waters derek@lj-oz.com
-
OCX uUid collision nightmarePerhaps the easiest solution would be to create a new ActiveX Control project from scratch, then add in all the files from your old project and tie them in to your new ActiveX "wrapper". (I have had to do this myself) ------------------------ Derek Waters derek@lj-oz.com
-
Go You Big Red Fire EngineMichael Martin wrote: A couple of years ago this became his catchphrase after an audience member yelled it out during a show. He encouraged everyone at his shows to continue to use this phrase everyday. There was a news item last year reportijng this as a phenomenom that was taking off. I do believe that Michael Armitage (an until-recently member of South Australian parliament) actually used it in the house (to much laughter from those who know Adam Hills and much confusion to the other 99.9% of politicians). I believe it was something about the state of SA's economy, which he attempted to encourage single-handedly with a cry of "go you big red fire engine"! ------------------------ Derek Waters derek@lj-oz.com