Win98 does not support UNICODE as is. You need to have a dll with your app (UNICOWS.dll). Try installing that on the Win98 system (in the system dir, or the dir your app goes in). No need to register it.
Main Topics
Browse All TopicsHi,
Thanks a lot in advance for resolving my query.
I have found that the class CComboBoxEx does not work on Windows 98 if compiled with _UNICODE flag. On Windows 98 we need the MSLU for Unicode to work. However the CComboBox is not able to InsertItems into its list in such projects.
I have created sample projects (dialog based) that simulate both the CComboBoxEx::InsertItem() over MSLU and without the _UNIOCODE flag compilation.
I find that InsertItem works without the _UNIOCDE flag compilation on Windows 98. However when i make it _UNICODE and have the MSLU layer included, i have the problem.
I will be posting the source code in another comment below.
I can send the zipped sample projects if somebody is interested.
Thanks and Regards,
Abdij
This Question has been solved and asker verified All Experts Exchange premium technology solutions are available to subscription members.
Experts Exchange has been collecting answers to technology questions since 1996…3 million and counting! If you have a question, chances are we already have your answer.
If you can't find the exact answer you're looking for, ask our exclusive community of 50,000 experts. You’ll get a personalized answer from a trusted professional.
Thousands of free tech tips, tricks, how-to’s and tutorials are available in our peer reviewed articles section. See for yourself how smart our experts are, no login required.
Access the answers to your technology questions today.
30-day free trial. Register in 60 seconds.
Members of the expert community talk about why the experience at Experts Exchange is different than what you will find anywhere else.

Try it out and discover for yourself.
30-day free trial. Register in 60 seconds.
Join the community of experts here and help other tech pros by answering question in your area of expertise. You can earn FREE access to all Experts Exchange's premium features and resources.
Hi AndyAinscow,
We do have the Unicows installed on the Win 98 system. Also we have followed the correct procedure for building using the Unicows and MSLU. That is the reason we have the application up (otherwise it would crash at ::LoadCursor() during runtime intialization).
Hence Unicows is not the issue. The issue is that the API concerned is not working. Please note there are hundreds of other API's (including the CComboBox API's) that work.
Please advice.
Regards,
Abdij
Hi Migel,
A good idea, but unfortunately we are the end of the project and are suddenly facing this problem. If i do that, then there might be lot of area's that i need to relook.
However, i agree that the idea is a good one. I will try it out in a sample and see if it can be merged with my main application seamlessly. If the cost of integration is more, we will have to look at some other option.
But, my fundamental query is: WHY SHOULD THE API FAIL? WHY IS IT NOT DOCUMENTED IN MSDN or SOMEWHERE IN MICROSOFT SITE? WHY IS IT NOT LISTED IN THE LIST OF API's UNSUPPORTED OVER MSLU?
Certainly this is not good stuff from MS.
Regards,
Abdij
Hi Migel,
I tried doing it, but it does not work.
Here is what i did. I had CMyComboBoxEx derived from CComboBoxEx. I added a handler for the CBEN_INSERTITEM and a whole bunch of other controls.
However i find that the OnInsertitem() function which is the handler for CBEN_INSERTITEM is never called, inspite of the call to InsertItem() in the code. However strangely other functions do get called.
Regards,
Abdij
Hi!
code please :-)
note that UNICODE VERSION uses CBEN_INSERTITEMW message
handle can look like this:
LRESULT CMyComboBoxEx::OnInsertIte
{
COMBOBOXEXITEMW* pComboW = (COMBOBOXEXITEMW*)lp;
COMBOBOXEXITEMA itemA;
// copy here from pComboW to itemA
// and convert text to ANSI one
return SendMessage(CBEN_INSERTITE
}
Hi Migel,
When i derived my class from CComboBoxEx and added the handler from ClassWizard, the handler looked like void CMyComboBoxEx::OnInsertite
Also when i do a InsertItem(&cbItem); i see that the MFC sends the CBEN_INSERTITEM message. I do not know if it internally translates to CBEN_INSERTITEMW on Unicode (as i cannot debug!).
However i see that the code never comes to the handler.
Can you please post a sample code for me please?
Thanks and Regards,
Abdij
Hi Migel,
Apart from adding the classwizard handler for CBEN_INSERTITEM, i have done nothing. I wait on a breakpoint there.
Also i tried mapping CBEN_INSERTITEMW to a function. But i got the error "error C2065: 'CBEN_INSERTITEMW' : undeclared identifier". The same for 'CBEN_INSERTITEMA'.
Please advice.
Thanks and Regards,
Abdij
Hi!
1. you use notify reflection - it is wrong solution in your case.
You need to manually add handler to the class by this code
BEGIN_MESSAGE_MAP(...)
/// here !!!
ON_MESSAGE(CBEN_INSERTITEM
//// rest of message map
2. You use old commctrl.h file - it shows you old comctl32.dll interface - in this case your solution simlpe
just replace CBEN_INSERTITEMW to CBEN_INSERTITEM - since old versions doesn`t distinct UNICODE and ANSI versions.
Business Accounts
Answer for Membership
by: abdijPosted on 2003-09-15 at 01:59:14ID: 9361318
The Source Code--->
********** ********** ******
********** ********** *
g)
xDlg) ge* pDX); // DDX/DDV support
)
_H__07AFF3 20_FF72_46 C6_8514_9E A7E7244EF4 __INCLUDED _)
********** ********** *
********** *********
og()
S_ABOUTBOX ); PARATOR); RING, IDM_ABOUTBOX, strAboutMenu);
->LoadIcon (IDI_FOLDE R_CLOSE_IC O)); ->LoadIcon (IDI_FOLDE R_OPEN_ICO )); ->LoadIcon (IDI_INSP_ SCRIPT_ICO )); ->LoadIcon (IDI_DRIVE _ICO)); ->LoadIcon (IDI_FLOPP Y_ICO)); ->LoadIcon (IDI_DRIVE NET_ICO)); ->LoadIcon (IDI_CDDRI VE_ICO));
t(&m_cImgL ist);
*CToolBase *pToolData*/) BEIF_SELEC TEDIMAGE|C BEIF_TEXT; t();
, (LPTSTR)chDrivesBuf); ze); e + 1];
rivesActua lBufSize, (LPTSTR)chDrivesBuf);
ze);
Length() - 1); // strip of ending slash
&CBItem);
csStartFolder);
\")) == 0) // get rid of the first slash
iItem++) Item, strItem);
); ;
&CBItem);
Item - 1);
(CString& csRootDir, CString& csStartFolder)
);
;
r, NULL);
r, NULL);
;
, NULL))
r, NULL);
r, NULL);
own(UINT nFlags, CPoint point) ags, point);
********** ********** ********** ****
//************************
Header File
//************************
class CComboBoxExDlg : public CDialog
{
// Construction
public:
CComboBoxExDlg(CWnd* pParent = NULL); // standard constructor
// Dialog Data
//{{AFX_DATA(CComboBoxExDl
enum { IDD = IDD_COMBOBOXEX_DIALOG };
CComboBoxEx m_cDirectoryCB;
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CComboBoxE
protected:
virtual void DoDataExchange(CDataExchan
//}}AFX_VIRTUAL
// Implementation
protected:
HICON m_hIcon;
// CDirectoryList m_cDirListObj;
CString m_csRootFolder;
CString m_csCurInspDir;
CString m_csTemplateFile;
CBitmap m_cBkListImg;
// eFILE_TYPE m_eSelectedFileType;
CImageList m_cImgList; // image list used for both the
// combox box and list view
// indexes into the image list for the different
// icons
int m_nFOLDER_CLOSE_INDEX;
int m_nFOLDER_OPEN_INDEX;
int m_nINSPEC_SCRIPT_INDEX;
int m_nDRIVE_INDEX;
int m_nFLOPPY_INDEX;
int m_nDRIVENET_INDEX;
int m_nCDDRIVE_INDEX;
bool InitTool(/*CToolBase *pToolData*/);
void GetRootDir(CString& csRootDir, CString& csStartFolder);
// Generated message map functions
//{{AFX_MSG(CComboBoxExDlg
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_COMBOBOXEXDLG
//************************
Source File
//************************
BOOL CComboBoxExDlg::OnInitDial
{
CDialog::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(ID
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SE
pSysMenu->AppendMenu(MF_ST
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// now create image list for each entry
m_cImgList.Create(16, 16, ILC_MASK, 4, 4);
m_nFOLDER_CLOSE_INDEX = m_cImgList.Add(AfxGetApp()
m_nFOLDER_OPEN_INDEX = m_cImgList.Add(AfxGetApp()
m_nINSPEC_SCRIPT_INDEX = m_cImgList.Add(AfxGetApp()
m_nDRIVE_INDEX = m_cImgList.Add(AfxGetApp()
m_nFLOPPY_INDEX = m_cImgList.Add(AfxGetApp()
m_nDRIVENET_INDEX = m_cImgList.Add(AfxGetApp()
m_nCDDRIVE_INDEX = m_cImgList.Add(AfxGetApp()
// set image list
m_cDirectoryCB.SetImageLis
return TRUE; // return TRUE unless you set the focus to a control
}
bool CComboBoxExDlg::InitTool(/
{
COMBOBOXEXITEM CBItem;
CBItem.mask = CBEIF_INDENT|CBEIF_IMAGE|C
CString csStartFolder;
m_cDirectoryCB.ResetConten
// find all available drives
CString strDrivesBuf;
TCHAR* chDrivesBuf = new TCHAR[255];
DWORD dwDrivesActualBufSize = GetLogicalDriveStrings(255
ASSERT(dwDrivesActualBufSi
if(dwDrivesActualBufSize >= 255)
{
// buffer is too small, let's try again
delete[] chDrivesBuf;
chDrivesBuf = new TCHAR[dwDrivesActualBufSiz
dwDrivesActualBufSize = GetLogicalDriveStrings(dwD
ASSERT(dwDrivesActualBufSi
}
int iItem = 0;
TCHAR* nPos = chDrivesBuf;
while(*nPos != NULL)
{
CString strDrive = nPos;
nPos += strDrive.GetLength() + 1;
int nDriveType = GetDriveType(strDrive);
switch(nDriveType)
{
case DRIVE_FIXED:
CBItem.iImage = CBItem.iSelectedImage = m_nDRIVE_INDEX;
break;
case DRIVE_REMOVABLE:
CBItem.iImage = CBItem.iSelectedImage = m_nFLOPPY_INDEX;
break;
case DRIVE_REMOTE:
CBItem.iImage = CBItem.iSelectedImage = m_nDRIVENET_INDEX;
break;
case DRIVE_CDROM:
CBItem.iImage = CBItem.iSelectedImage = m_nCDDRIVE_INDEX;
break;
default:
continue;
}
strDrive = strDrive.Left(strDrive.Get
CBItem.iItem = iItem;
CBItem.pszText = (LPTSTR)(LPCTSTR)strDrive;
CBItem.iIndent = 0;
m_cDirectoryCB.InsertItem(
iItem++;
}
delete[] chDrivesBuf;
m_csTemplateFile.Empty();
// get working path and parse it
GetRootDir(m_csRootFolder,
TCHAR drive[_MAX_DRIVE];
TCHAR dir[_MAX_DIR];
TCHAR fname[_MAX_FNAME];
TCHAR ext[_MAX_EXT];
CString strRootFolder = m_csRootFolder + _T("\\");
_tsplitpath( strRootFolder, drive, dir, fname, ext );
CString strDir = dir + csStartFolder;
if(strDir.FindOneOf(_T("/\
{
strDir = strDir.Mid(1);
}
// find the drive in combo and add every folder to it
for (iItem = 0; iItem < m_cDirectoryCB.GetCount();
{
CString strItem;
m_cDirectoryCB.GetLBText(i
if(strItem.CompareNoCase( drive)==0)
{
iItem++;
break;
}
}
int iIndent = 1;
while(!strDir.IsEmpty())
{
CString strFolder;
int nPos = strDir.FindOneOf(_T("/\\")
if(nPos != -1)
{
strFolder = strDir.Left(nPos);
strDir = strDir.Mid(nPos + 1);
}
else
{
strFolder = strDir;
strDir = _T("");
}
CBItem.iItem = iItem;
CBItem.pszText = (LPTSTR)(LPCTSTR)strFolder
CBItem.iImage = m_nFOLDER_CLOSE_INDEX;
CBItem.iSelectedImage = m_nFOLDER_OPEN_INDEX;
CBItem.iIndent = iIndent;
m_cDirectoryCB.InsertItem(
iItem++;
iIndent++;
}
// now set current select
m_cDirectoryCB.SetCurSel(i
//OnSelchangeFolderCb();
return true;
}
void CComboBoxExDlg::GetRootDir
{
TCHAR szAppDir[MAX_PATH + 1];
TCHAR szFolder[MAX_PATH + 1];
CString csIDir, csSubFolder;
int nLen;
DWORD dwAttrib;
//CSecurityHelper cSecAttr;
// get the sub directory under the
// directory the banner app is running in
szAppDir[0] = NULL;
::GetModuleFileName(NULL, szAppDir, MAX_PATH);
// parse out base dir
nLen = _tcslen(szAppDir) - 1;
while(nLen > 0 && szAppDir[nLen] != _T('\\'))
{
nLen--;
}
szAppDir[nLen] = NULL;
_tcscpy(szFolder, _T("Inspection Folder") );
csRootDir = szAppDir;
csStartFolder = szFolder;
// make sure directory exists, if not create it
csIDir = szAppDir;
csIDir += _T("\\");
csIDir += szFolder;
dwAttrib = ::GetFileAttributes(csIDir
if(dwAttrib == (DWORD)-1)
{
//cSecAttr.CreateNullSec()
// create directory for inspections
CreateDirectory(csIDir, NULL);
// now create two sub directions
// one for images and one for inspections
csSubFolder = csIDir;
csSubFolder += _T("\\Reference Images");
// create directory for inspections
CreateDirectory(csSubFolde
// now create two sub directions
// one for images and one for inspections
csSubFolder = csIDir;
csSubFolder += _T("\\Inspections");
// create directory for inspections
CreateDirectory(csSubFolde
}
else if( !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY) )
{
// file exists, now let's make sure it is in fact
// a directory and not a file that the user created
// use a different name
_tcscpy(szFolder, _T("Inspection Folder 2") );
csStartFolder = szFolder;
csIDir = szAppDir;
csIDir += _T("\\");
csIDir += szFolder;
//cSecAttr.CreateNullSec()
// create directory
if(!CreateDirectory(csIDir
{
DWORD dwErr = GetLastError();
}
// now create two sub directions
// one for images and one for inspections
csSubFolder = csIDir;
csSubFolder += _T("\\Reference Images");
// create directory for inspections
CreateDirectory(csSubFolde
// now create two sub directions
// one for images and one for inspections
csSubFolder = csIDir;
csSubFolder += _T("\\Inspections");
// create directory for inspections
CreateDirectory(csSubFolde
} // end else
}
void CComboBoxExDlg::OnLButtonD
{
InitTool();
CDialog::OnLButtonDown(nFl
}
//************************
Please note that InitTool() is the function of importance. The other functions are support functions. Please note the Inserttem() in InitTool().
Thanks and Regards,
Abdij