|
Hi,
I have an editor in my application which has a find functionality implemented for it.The user will enter text in the editor and will try the Find option from menu.The problem is when I have n double byte characters(of japanese) in my text and say if I try to find an char or word which after the double byte chars then my search is displaced by n bytes.This issue happens only in japanese and the same application works fine in English.Going through the below blog which has a similar problem as that of mine I noticed that the problem is with the dependancy on ComCtrl 6 dll used in xp manifest theme.
http://www.insidercoding.com/post/2008/08/06/Visual-C2b2b-60-2b-XP-Manifest-3d3d-Problems.aspx
My application is also developed in vc6 and we use a manifest file for XP visual theme as below
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity
version="1.0.0.0"
processorArchitecture="X86"
name="wm"
type="win32"/>
<description>Merely an XP test.</description>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="requireAdministrator" uiAccess="false"/>
</requestedPrivileges>
</security>
</trustInfo>
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="X86"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>
</assembly>
And I also cannot move my application to unicode. There are ASCII functions in my code.MFC by default supports MBCS.Even after placing _MBCS in project settings doesnt solve my problem. When I debug the below code I found the problem with lstrlen which is returning n chars extra for n double byte chars in my text to find.This happens only when I debug the code in japanese OS , the same works fine when I debug the same application in English OS.
static
int
FindStrPos( LPSTR lpSrc, LPSTR lpFind, BOOL bMatchCase )
{
LPSTR p;
int pos = -1, len;
char szFind[FIND_LEN];
LPSTR lpStr;
lstrcpy( szFind, lpFind);
if( !bMatchCase ) {
len = lstrlen(lpSrc)+1;
lpStr = (LPSTR)wwHeap_AllocPtr( hChunkWM,
(GMEM_MOVEABLE | GMEM_ZEROINIT), len );
if( lpStr ) {
_fmemcpy( lpStr, lpSrc, len );
_fstrupr( lpStr );
_fstrupr( (LPSTR)szFind );
p = _fstrstr( lpStr, (LPSTR)szFind );
if( p ) {
pos = p - lpStr;
}
wwHeap_FreePtr( hChunkWM, lpStr );
return( pos );
} else {
debug("Alloc failed compare case-sensitive");
}
}
p = _fstrstr( lpSrc, lpFind );
if( p )
pos = p - lpSrc;
return( pos );
}
I also used MBCS functions like _mbslen instead of lstrlen and _mbsstr instead of _fstrstr then _mbslen is returning accurate length in japanese and when while finding the difference between the search position and actual text pos the value of pos is again added with n bytes in japanese version for n double byte chars in Text.
I tried removing the manifest file as the unknown problem is with the dependancy of comcontrl dll version 6 for enabling Xp style but it is giving other problems in japanese.
Any suggestion would be helpful.
Thanks,
Satya
Today is a gift, that's why it is called the present.
|
|
|
|
|
I dont understand your problem point yet. Will you explain the point for short again?
|
|
|
|
|
Sure ..
say with a text having 6 double byte chars as below and if I try to find word My then my search is displaced by 6 chars
and the pos is returned at "th"
" DIM a;DIM b;{ ‚ ‚¢‚¤‚¦‚¨‚ ‚¢‚¤‚¦‚¨‚ ‚¢‚¤‚¦‚¨ } My Month "
using ascii version functions in my code
len = lstrlen(lpSrc)+1;
_fstrstr( lpStr, (LPSTR)szFind );
if( p ) {
pos = p - lpStr;
}
Using MBCS functions
len = _mbslen((unsigned char *)lpSrc)+1;
ucP = _mbsstr((unsigned char *)lpStr, (unsigned char *)(LPSTR)szFind );
if(ucP)
{
pos = ucP - (unsigned char *)lpStr;
}
This problem happens only in japanese OS and that too in my application's editor.
Removing the XP manifest file from my application folder seems to work fine.
Doing a sample application of the same and testing in both english and japanese OS is working fine.
Now I am changing my code to MBCS and then counting the double byte chars in my code and adjusting the position accordingly using below code.
int cPos = 0,count =0;
while(cPos<pos)
{
if( IsDBCSLeadByte(lpStr[cPos] ))
{
cPos = cPos + 2;
count++;
}
else
cPos++;
}
pos = pos - count;
Thanks
Satya
Today is a gift, that's why it is called the present.
|
|
|
|
|
Hi All ,
I am having a Project.lib and i need to convert it into Project.dll
When i Build Project.dll i am getting linker errors:
Sample.lib(Program.obj) : error LNK2001: unresolved external symbol "public: __thiscall Method::Method(void)" (??0Method@@QAE@XZ)
Sample.lib(Program.obj) : error LNK2001: unresolved external symbol "public: __thiscall Method::~Method(void)" (??0Method@@QAE@XZ))
Debug/Project.dll : fatal error LNK1120: 2 unresolved externals
Error executing link.exe.
I have added the Sample.lib to added Project Settings to be Linker and this class Method is used as Base class to one of the classes in Program.obj
The definition and declaration for class Main is in another Project all together which is an exe.
How can i solve this error?
Thanks for your time,
Hari
|
|
|
|
|
You got no MSDN installed?
...byte till it megahertz...
|
|
|
|
|
|
How would MSDN fix a linker issue?
It's time for a new signature.
|
|
|
|
|
Pfff. Doesn't it tell why this error is issued and isn't that good enough to fix it? Even simply googling would have lead to online MSDN, if he didn't have it installed, along with scores of other sites that tell the same thing.
...byte till it megahertz...
|
|
|
|
|
bleedingfingers wrote: Doesn't it tell why this error is issued and isn't that good enough to fix it?
Possibly, but rather than ask if he has it installed you could have posted a link to the page with the solution so the OP understands what you meam.
It's time for a new signature.
|
|
|
|
|
Yeah, must have. I figured he could get what I meant but he didn't seem to
...byte till it megahertz...
|
|
|
|
|
This typically looks like you forgot to provide a body for the constructor and destructor of your Method class.
|
|
|
|
|
You have a call to a Method() constructor and destructor in your module Program, but you have not included the body of the class in your project. Alternativel you need a extern "C" declaration around your class.
It's time for a new signature.
|
|
|
|
|
I try this way ,but feel it doesn't safety.
#include "TestDlg.h"
class CMainDlg : CDialog
{
public:
CTestDlg *m_pTestDlg;
void ShowDlg();
void FreeDlg();
}
void CMainDlg::ShowDlg()
{
m_pTestDlg = new CTestDlg();
m_pTestDlg->Create(IDD_TEST_DLG,this);
m_pTestDlg->CenterWindow();
m_pTestDlg->ShowWindow(SW_SHOWNORMAL);
m_pTestDlg->UpdateWindow();
}
void CMainDlg::FreeDlg()
{
if( m_pTestDlg != NULL )
{
delete m_pTestDlg;
}
}
Is this right ?
How to safty free the memory ?
Thanks for your reply !
Best Regards !
|
|
|
|
|
You could try the following :
void CMainDlg::FreeDlg()
{
if (m_pTestDlg) {
if (m_pTestDlg->GetSafeHwnd()) {
m_pTestDialog->EndDialog(IDCANCEL);
}
delete m_pTestDlg;
m_pTestDlg = NULL;
}
}
void CMainDlg::OnDestroy()
{
FreeDlg();
}
virtual void BeHappy() = 0;
|
|
|
|
|
Another point is that there is no point in having a pointer for your dialog if you at any point are worried about memory. You could just use CTestDlg m_testDlg;
Using a pointer as you have has only one advantage. You can use a forward declaration of CTestDlg in your header file to avoid compile time dependencies. This will reduce compilation time if you later make changes to CTestDlg. In practice, this applies to large project only.
Also, the UpdateWindow() call is superfluous.
|
|
|
|
|
Normally I'd agree about using a member rather than a dynamically created object. However in the case of a modeless dialogue box you can have the problem of resetting the members of the dialogue (if the dialogue box is closed and reopened) which can lead to some funky fiddling with manually calling destructors and placement new. As soon as you start thinking about that you might as well just say sod it and recreate the object as you need to use it.
Cheers,
Ash
Edited as I said completely the wrong thing and confused Niklas. Sorry!
modified on Thursday, August 19, 2010 7:26 AM
|
|
|
|
|
When having a modal dialog I have never found the use of dynamically allocate the object. I just create it as automatic on the stack in whatever function I need it.
|
|
|
|
|
If I had a brain I'd be dangerous. I should really proof read what I write more. There was a finger faux-pas in my response, I should have said "modeless."
For a modal dialogue I wholeheartedly agree - you'd be cracked to not stick it on the stack.
Cheers,
Ash
|
|
|
|
|
A quick point...
IF you're creating a modeless dialogue box (created with Create) then make sure you kill it off using DestroyWindow, not EndDialog.
IF you do and you're sure that CTestDlg is only going to be created dynamically then overide PostNCDestroy to clean up the C++ object. It's a bit disgusting but there are so many MFC classes that do it you might as well join in the fun! The advantage is that all you have to do is destroy the window and it'll clean up after itself:
void CTestDialog::PostNCDestroy()
{
delete this;
}
Cheers,
Ash
|
|
|
|
|
The statement "delete this" is amusing. I always add the comment "// hari kari".
Anyway, common practice is to keep a pointer to the modeless dialog in the object that creates it so you can just bring it forward if it is reinvoked ie., the pointer is not null. What I do in this case is I pass the address of that pointer to the dialog object so it can null it when it is closed - usually preceding the "delete this" statement. The PostNCDestroy method then looks like this :
void CTestDialog::PostNCDestroy()
{
if( m_pSelf )
*m_pSelf = NULL;
delete this;
}
That is the best and easiest way I have come up with to deal with the issue so far.
|
|
|
|
|
in addition to what Aescleal told, over-riding PostNcDestroy is useful when you are dealing with a number of pop up child windows and letting the user to close them dynamically.
|
|
|
|
|
Does it have some functions? to get the file nubmers of the whole computer? How does the vir killer software to do that,how could they control the progress of the whole files of the computer?
I am not a genius, but shed more sweat!
|
|
|
|
|
|
I have what seems to be a random deadlock in my application which I am hoping someone can shed some light on.
The occurance of the deadlock is random but the call stack is far from it... below is the stack I am getting.
0:001> ~0s;kbn
eax=002f0f60 ebx=00000000 ecx=00000f60 edx=00000f60 esi=0079cc10 edi=0015ec54
eip=61088bc4 esp=0015ea90 ebp=0015ebd0 iopl=0 nv up ei pl nz na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000206
mfc90ud!CWnd::OnWndMsg+0x224:
61088bc4 335508 xor edx,dword ptr [ebp+8] ss:002b:0015ebd8=00000087
# ChildEBP RetAddr Args to Child
00 0015ebd0 61088962 00000087 00000000 00000000 mfc90ud!CWnd::OnWndMsg+0x224
01 0015ebf0 61085d80 00000087 00000000 00000000 mfc90ud!CWnd::WindowProc+0x32
02 0015ec6c 61086346 0015f884 000b1068 00000087 mfc90ud!AfxCallWndProc+0xf0
03 0015ec8c 61081a3b 000b1068 00000087 00000000 mfc90ud!AfxWndProc+0xa6
04 0015ecc8 750c6238 000b1068 00000087 00000000 mfc90ud!AfxWndProcBase+0x5b
05 0015ecf4 750c68ea 610819e0 000b1068 00000087 USER32!InternalCallWinProc+0x23
06 0015ed6c 750ccd1a 00000000 610819e0 000b1068 USER32!UserCallWinProcCheckWow+0x109
07 0015edb0 750ccd81 00c8ba70 00000000 610819e0 USER32!SendMessageWorker+0x581
08 0015edd4 750e0fb1 000b1068 00000087 00000000 USER32!SendMessageW+0x7f
09 0015ee00 750e29a2 00cadd90 00000000 00c87810 USER32!xxxRemoveDefaultButton+0x5f
0a 0015ee30 750dc0cd 00cadd90 00000000 00290b46 USER32!xxxCheckDefPushButton+0x12d
0b 0015ee68 610eebb3 001e0ada 00000000 f53163fb USER32!IsDialogMessageW+0x156
0c 0015ee80 6108f76e 0079cbc8 0058cff8 0015eea8 mfc90ud!CWnd::IsDialogMessageW+0x73
0d 0015ee90 610c730f 0079cbc8 0058cff8 0058cff8 mfc90ud!CWnd::PreTranslateInput+0x6e
0e 0015eea8 6108afbd 0079cbc8 0058cff8 00190712 mfc90ud!CDialog::PreTranslateMessage+0xef
0f 0015eebc 611174df 001e0ada 0079cbc8 0015eedc mfc90ud!CWnd::WalkPreTranslateTree+0x8d
10 0015eed8 61118595 0079cbc8 002f9940 0015eef8 mfc90ud!AfxInternalPreTranslateMessage+0x4f
11 0015eee8 61117555 0079cbc8 002f9940 0015ef18 mfc90ud!CWinThread::PreTranslateMessage+0x25
12 0015eef8 61117391 0079cbc8 0015ef14 61081be9 mfc90ud!AfxPreTranslateMessage+0x25
13 0015ef18 611188ee 002f9940 0015ef30 611173e1 mfc90ud!AfxInternalPumpMessage+0xe1
0:000> .frame c
0c 0015ee80 6108f76e mfc90ud!CWnd::IsDialogMessageW+0x73
0:000> dv
this = 0x0058cff8
lpMsg = 0x0079cbc8
0:000> dt lpMsg -r
Local var @ 0x15ee88 Type tagMSG*
0x0079cbc8
+0x000 hwnd : 0x000a0bb6 HWND__
+0x000 unused : ??
+0x004 message : 0x201
+0x008 wParam : 1
+0x00c lParam : 917536
+0x010 time : 0x32b9eaf
+0x014 pt : tagPOINT
+0x000 x : 2742
+0x004 y : 915
Now the stack from USER32!SendMessageW+0x7f is pretty consistent and it always seems to be message 0x201 (WM_LBUTTONDOWN). Once in this state control is never returned to my code so I am sure I am missing something but I do not know what.
I don't have any code that is looking for WM_LBUTTONDOWN and I have not set anything relating to it, as far as I can tell, and I know when the problem occurs I have not been anywhere near the LBUTTON on my mouse!?!?
In searching around I came across a site in German that says the problem is caused by missing WS_GROUP from the RC. So I added some and I am still having the same problem.
If anyone has had this before and/or can give me some ideas as to what I am missing I would appreciate it.
Many thanks
Alan
|
|
|
|
|
After a little more digging I have discovered that I am getting stuck in a loop inside CWnd with a WM_GETDLGCODE being passed to all of the controls in my application?|?|? The main dialog consists of
BEGIN
CONTROL "",IDC_MNG_TAB,"SysTabControl32",0x0,17,25,248,300
PUSHBUTTON "Edit",IDC_MNG_EDIT,31,345,51,14,WS_GROUP
PUSHBUTTON "Apply",IDC_MNG_APPLY,112,345,50,14,WS_DISABLED | WS_GROUP
DEFPUSHBUTTON "Cancel",IDC_MNG_CANCEL,194,345,50,14,WS_GROUP
CONTROL "",IDC_MAIN_TREE,"SysTreeView32",WS_BORDER | WS_HSCROLL | WS_GROUP | WS_TABSTOP,299,75,209,250
CONTROL "",IDC_RPT_TAB,"SysTabControl32",0x0,544,25,248,300
PUSHBUTTON "Execute",IDC_RPT_EXECUTE,561,345,50,14,WS_GROUP
PUSHBUTTON "Cancel",IDC_RPT_CANCEL,724,345,50,14,WS_GROUP
CONTROL 284,IDC_LOGO,"Static",SS_BITMAP,299,329,209,39
GROUPBOX "Manage",IDC_MNG,7,7,268,369
GROUPBOX "Monitor",IDC_MONITOR,285,7,237,369
GROUPBOX "Report",IDC_RPT,532,7,268,369
GROUPBOX "Status",IDC_ST_STATUS,299,21,209,44
CONTROL 0,IDC_STATUS,"Static",SS_BITMAP,324,31,159,28
END
The group boxes and tab controls are owner drawn.
Any help would be appreciated.
Alan
|
|
|
|
|