|
The firt thing to do would be to add the following two directives to the top of the project's stdafx.h file:
#define UNICODE
#define _UNICODE Now compile the project and you'll see what statements need to be changed.
"The largest fire starts but with the smallest spark." - David Crow
"Judge not by the eye but by the heart." - Native American Proverb
|
|
|
|
|
Unicode means using "wide chars".So any code using char* will need to be checked&MODIFIED .You should particulary pay attention to the places where you pass the size of the string in bytes since
strlen(string)is the good size (in bytes) for non unicode but not for unicode.
Basically you should(VC6.0):
1)Add an "Unicode Debug" and an "Unicode Release" configuration (Build/configurations)
2)define UNICODE and _UNICODE in the *project settings* AND REMOVE the define _MBCS for the defined configurations.Also Change the entrypoint(Tab"Link",Category:"output")from empty to "wWinMainCRTStartup"(if you are using MFC)
3)Surround any text in code with _T() like : _T("text here")
4)Search in MSDN "Routine Mappings" to find out what string functions you should replace and with what(Ex:_tcslen instead of strlen)and relace them.Replace any "char" with "TCHAR" if it is used for strings.
5)Change the font for all dialogs to one that supports Unicode (Like Arial,Tahoma)
6)Pray to god you haven't missed something,Compile,Fail to link,notice that you have dependencies that are not unicode and start all over again.
Sorry for the bad news.
|
|
|
|
|
Actually, i've posted this question after going trough steps 1 to 6 (minus the start all over again part) and I was hoping for an easyer aproach.
So basically i'm up to my ears into a summer of search and replace plus one month of serious debugging. I hate programmers that don't use unicode by default for their applications(myself included )
|
|
|
|
|
Hi,
I want to insert a HBitmap object in the CRichEditCtrl. For this purpose I am using the CImageDataObject class (defined by the following open-source project)
http://www.codeguru.com/cpp/controls/richedit/article.php/c5383/[^]
My problem is that it works fine if I use the bitmaps which are loaded from resources. but gives a Memory exception if I create my own bitmap.
My bitmap creation function is given as follows
HBITMAP MyImage::MakeBitmap2()
{
if (!pDib)
return NULL;
HBITMAP handle = NULL;
HDC dc = ::CreateCompatibleDC(NULL);
if (dc)
{
// tmpBitmap is a dummy, to satisfy ::CreateCompatibleDC (it
// is a memory dc that must have a handle selected into it)
BITMAPINFO bi;
ZeroMemory(&bi, sizeof bi);
bi.bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
bi.bmiHeader.biWidth = GetWidth();
bi.bmiHeader.biHeight = GetHeight();
bi.bmiHeader.biPlanes = 1;
bi.bmiHeader.biBitCount = 24;
VOID* pvBits;
handle =CreateDIBSection(dc, &bi, DIB_RGB_COLORS, &pvBits, NULL, 0);
if (handle==NULL)
{
return NULL;
}
HBITMAP oldBitmap = (HBITMAP) ::SelectObject(dc, handle);
StretchDIBits(dc, 0, 0, head.biWidth, head.biHeight, 0, 0, head.biWidth, head.biHeight,
info.pImage,(BITMAPINFO*)pDib, DIB_RGB_COLORS,SRCCOPY);
::SelectPalette(dc, NULL, TRUE);
::SelectObject(dc, oldBitmap);
::DeleteDC(dc);
}
return handle;
}
I am already using this function for doing some other image related tasks and it is working fine,
So can any body tell me why isn't it working with that object.
|
|
|
|
|
|
In my program, I have installed a WH_CBT hook on a filter function. I want to monitor window creation event.
Problem is I am getting more than 1 notifications when a single window is created.
Example when a dialog box was created I was getting more than 1 notification (in range 3-10)
I wanted only a single notification.
waiting for reply
Thanks
-- modified at 7:19 Friday 23rd June, 2006
|
|
|
|
|
define a BOOL variable
BOOL windowCreated = FALSE;
then in your windows procedure.
if(windowCreated==FALSE)
{
msgbox..
windowCreated=TRUE;
}
Row
|
|
|
|
|
Assume i have a base class A (which contains a virtual function "test") and its derived class B (implement the virtual function).
Now i do :-
A* a = new A;
memset( a, 0, sizeof( A ) );
a->test(); // here it crashes??
Why?
Thanks...
Heaven is a girl I know so well
She makes me feel good when I feel like hell
Heaven is a girl that I've got to have
And she makes me feel better when I'm feelin' bad
Heaven is a girl that makes dreams come true
Oh, no one does it good like heaven do, yeah
|
|
|
|
|
I'm not totally sure but I think the reason is because once you have a virtual function in your class, you will have a virtual function table added in the class. That is, a table that will redirect the call to a function to the specific function (base or inherit) in function of the type of the object. So, if you 'erase' this table with 0, if you try to call a function within this table, you will try to call a function at memory location 0, which causes a crash.
Cédric Moonen
Software developer
Charting control
|
|
|
|
|
You are correct. This is a classic example of what goes wrong when you mix low level constructs with high level ones without a well developed understanding of how the high-level constructs are implemented. Every class that has virtual functions has a virtual function table; one table is shared between all instances of that class. It contains pointers to virtual functions (or sometimes adjustor thunks to the virtual functions if multiple inheritance is used). When the constructor of a class with virtual functions is called it initializes a pointer in the instance data to point to the class’s vtable: this is the pointer that's being overwritten. In short, if you use simple structs and classes (no virtual functions or multiple inheritance) the layout of the class is what you would naively expect; if you have a struct or class with high-level constructs such as virtual functions or multiple inheritance the layout of the class as a whole will not be so predictable and will contain the book keeping info needed to implement them.
Steve
|
|
|
|
|
Just to be more precise: the v-table is not in the object itself, but somewhere in the system.
Its leading address is in the object, and part of the object size, as the virtual base table address (if any).
What is erased is not that table itself, but the table address, hence, by invoking a virtual function, you'll try to find the address by seeking the corresponding entry considering the memory "0" to be the table.
The crash is not the function invoke, but the attempt to read an invalid memory page to detect wich function to invoke.
2 bugs found.
> recompile ...
65534 bugs found.
|
|
|
|
|
I think main idea behind virtual functions is they r there only so that derived classes could make use of it.
If u had written
A* a = new B ;
ur code would have worked fine.
I have not refreshed c++ from last 8 months if I am wrong anybody cancorrect me
bye.
|
|
|
|
|
|
I posted before his reply. anyway i will make use of information
|
|
|
|
|
|
u r almost right, I was in my own world
to be honest I had written my suggestion when nobody had presented reply to the original question, but I failed to press submit.
If I was totally wrong I would not have replied.
why waste our time unnecessarily on useless point.
bye(this time really)
|
|
|
|
|
Sometimes when you start a reply you're the first but you take some time to write it and by the time you send it it's out of date; it has happened to me before today.
Steve
|
|
|
|
|
toxcct wrote: man, either you have a problem in your time management, or you didn't refresh your browser :
It's happened to me a few times that I've replied and found someone's replied before me.
Regards,
Nish
|
|
|
|
|
LordsAngel wrote: memset( a, 0, sizeof( A ) );
Why the heck are you doing this ?
Maximilien Lincourt
Your Head A Splode - Strong Bad
|
|
|
|
|
A plain C habbit maybe ? In C, for initalizing all data members of a struct, it is quite practical to use such mechanism.
Cédric Moonen
Software developer
Charting control
|
|
|
|
|
As a rule in C++, never initialize a struct /class using memset . That's what constructors are for.
Software Zen: delete this;
|
|
|
|
|
There is nothing wrong with initializing a class /struct with memset if you know what you're doing. The basic rule is only use memset on class s/struct s which:
- Don't have any virtual functions.
- Don't have any virtual base class es.
The above two restrictions are also recursive into the classes members. For example a class itself may not have any virtual functions but some its members may and so it is NOT safe to use memset on it.
While you are correct that "that's what constructors are for" there is little doubt that when it is safe to do so it will be more efficient. Most times the efficiency gain will not be worth it but, as always, there will be exceptions.
If you really want to use memset but still want to use have virtual functions you can do so like this:
struct CMyClass_Data
{
CMyClass_Data()
{
memset(this, 0, sizeof(*this));
}
};
class CMyClass : private CMyClass_Data
{
public:
virtual VFun1() { }
virtual VFun2() { }
}
Steve
|
|
|
|
|
While what you say is true, it still skates closer to the edge than I prefer. I use memset to initialize simple buffers and other types of POD (plain old data), and that's about it. I do use this construct, however:
struct MyData {
...
};
MyData data = { 0 }; in preference to memset most of the time. In this case, the compiler will complain if anything in type MyData has a non-trivial constructor, which guarantees at compile time that the operation is safe.
Software Zen: delete this;
|
|
|
|
|
I've got nothing against this technique and use it myself; but it can't achieve exactly the same result as the example I gave. If you want the members that you're ={0} ing to be members of the class with virtual functions this technique can't be used. I reiterate - in general I wouldn't bother with such confusing constructs - but there are exceptions to every rule.
Steve
|
|
|
|
|
Stephen Hewitt wrote: exceptions to every rule
Well, as long as you catch them properly...
Software Zen: delete this;
|
|
|
|