BenoitRen Posted November 21, 2008 Author Posted November 21, 2008 Argh, it does still have the problem. Maybe I should give up on RICHED32.DLL and use RICHED20.DLL instead.
BenoitRen Posted December 4, 2008 Author Posted December 4, 2008 (edited) I'm using RICHED20.DLL now. I snagged it from the Microsoft Installer 2.0 update package. This does fix the problem. It also gives me multiple undo capability and Unicode.MSDN says that if I use the control in Unicode mode, it will expect Unicode messages. What does this mean? Can someone shed some light on this?EDIT: What it actually says: "In Rich Edit 2.0, if you create a Unicode rich edit control (one that expects Unicode text messages), you must specify only Unicode data in any window messages sent to the control." Edited December 4, 2008 by BenoitRen
Mijzelf Posted December 5, 2008 Posted December 5, 2008 I *think* you should use SendMessageW and PostMessageW for all messages containing or retreiving stringdata, and use the widestring variant of the structs.SendMessageW( hwnd, WM_SETTEXT, 0, (LPARAM) L"Text" );wchar_t buffer[ 32 ];SendMessageW( hwnd, WM_GETTEXT, 32, (LPARAM)buffer );FINDTEXTW ft = { ... };SendMessageW( hwnd, EM_FINDTEXT, FR_DOWN, (LPARAM) &ft );
BenoitRen Posted December 7, 2008 Author Posted December 7, 2008 (edited) I just tried to find how to convert an ANSI string to a UTF-8 string, and there's no place that gives a clear answer in code. The closest I found was on CodeProject, and that was to represent UTF-8 in only the first 128 ASCII characters.I'd have to find out how to detect a UTF-8 encoded file upon opening, too.All this Unicode stuff is doing my head in. EDIT: You have to do MultibyteToWideChar and then WideCharToMultibyte. However, encoding to UTF-8 is only supported on Windows 98 and later, unless I use the Microsoft Layer For Unicode. I give up, unless someone has a work-around. Edited December 7, 2008 by BenoitRen
BenoitRen Posted December 7, 2008 Author Posted December 7, 2008 (edited) Now I have a different problem. I want to disable the Save menu item when no changes have been made. First I tried to use EnableWindow for this purpose. That didn't work. So I did a Google search, and found that I needed to use EnableMenuItem. I used it like described on the page and in Borland's reference, and came up with this:EnableMenuItem(GetMenu(hwnd), ID_FILE_SAVE, MF_GRAYED);However, it still doesn't work! What am I doing wrong?By the way, since switching to Rich Edit Control 2.0, search is done backwards, with only one result found each time. What the hell is this?!EDIT: And now the menu item graying works fine. Did I forget to compile, or something? :/ EDIT: Indeed. I caught myself running my program after making changes without compiling first. Edited December 7, 2008 by BenoitRen
Mijzelf Posted December 7, 2008 Posted December 7, 2008 Have a look here:http://en.wikipedia.org/wiki/UTF-8#Description UTF-8 uses 1,2,3 or 4 bytes a character depending on the numerical value of the (unicode) character. When saving a file in UTF-8, notepad will add a header 0xEF 0xBB 0xBF. A file starting with this sequence you can consider UTF-8 encoded. Another file *might* be UTF-8 encoded too, but there's no way to be be sure. Read this. Ansi is a 'strange' standard (actually it isn't a standard), so the best way to convert Ansi to UTF-8 is converting it to unicode with MultibyteToWideChar, and then convert this to UTF-8.
BenoitRen Posted December 7, 2008 Author Posted December 7, 2008 When I replaced the RICHED20.DLL file I had by a more recent one, the search bug went away. But now it's back again!I've been trying, in vain, to make my program open a file specified at the command line. Here's what I've done to achieve that. In my WinMain I have:if (*lpCmdLine != NULL) strcpy(g_szFileName, lpCmdLine);If there's something in the command line, it gets copied into my global variable that holds the path to the opened file. It's defined near the top of my source as follows:char g_szFileName[MAX_PATH] = "";This seems to work, as when I show the variable's contents using a MessageBox, I get what I inputted at the command line. Next, in my window process' WM_CREATE event, I do:if (*g_szFileName != NULL) { if (loadFile(g_szFileName) == TRUE) SetWindowText(hwnd, strcat(g_szFileName, " - Kladblok")); else MessageBox(hwnd, "Er was een fout tijdens het openen van het bestand.", "Fout", MB_ICONEXCLAMATION | MB_OK);;}But this doesn't work. For some reason when my program gets here g_szFileName is empty! I verified with a MessageBox.
Mijzelf Posted December 7, 2008 Posted December 7, 2008 By the way, since switching to Rich Edit Control 2.0, search is done backwards, with only one result found each time. What the hell is this?!There is a difference between v1 and v2: http://msdn.microsoft.com/en-us/library/bb788009(VS.85).aspx. Did that bite you?For some reason when my program gets here g_szFileName is empty!Then it's overwritten or hidden by another variable. Did you declare some array directly before or after g_szFileName? Check if you don't exceed their bounds. You don't have a debugger, I suppose?
BenoitRen Posted December 7, 2008 Author Posted December 7, 2008 Thanks, that difference did bite me. What a nasty default behaviour.I wouldn't know how I'm exceeding any bounds. The char array I have is definitely big enough. Here's my source code if you have time to look into it. I do have the Turbo Debugger, but I can't figure out how to work with it.
code65536 Posted December 7, 2008 Posted December 7, 2008 IIRC, CreateWindow calls WndProc with WM_CREATE before returning.Also, if you create your RichEdit text box with CreateWindow(Ex)W, then it's a Unicode text box. Create it with CreateWindow(Ex)A, then it's non-Unicode. There's really no reason you should be using non-Unicode in this day and age. All the APIs in WinNT are natively Unicode, so you are incurring extra thunking costs every time you use one of those outdated "A" APIs.
Mijzelf Posted December 8, 2008 Posted December 8, 2008 Then it's overwritten or hidden by another variable.I forgot the 3rth possibility. It's not yet filled. You read g_szFileName in WM_CREATE, which is called inside CreateWindowEx() in WinMain(). g_szFileName is filled after this.FYI, I didn't see this directly, so I did some debugging-without-debugger magic. I exchanged char *g_szFileName[MAX_PATH] = "";by#define _DEBUG #ifdef _DEBUG char *fun_szFileName(int line) { static char _szFileName[MAX_PATH] = ""; char buf[ 16 ]; MessageBox( 0, itoa( line, buf, 10 ), "szFileName", MB_OK ); return szFileName; } #define g_szFileName fun_szFileName(__LINE__) #else char *g_szFileName[MAX_PATH] = ""; #endifNow it's easy to see when and from where g_szFileName is accessed. For more complex problems you'd better use a logfile instead of a messagebox.
BenoitRen Posted December 8, 2008 Author Posted December 8, 2008 Ah, I see. I've learned something new about the Windows API. code65536, this is for Windows 95, where not all the W APIs are available.
BenoitRen Posted December 12, 2008 Author Posted December 12, 2008 How do you activate word-wrap in a RichEdit control? Borland's WINAPI documentation only seems to mention how to replace the function used to do the actual wordwrapping.
BenoitRen Posted December 14, 2008 Author Posted December 14, 2008 (edited) Now I'm very confused. Text replacing doesn't work anymore. It does work with RichEdit version 1, but the CHARRANGE members have the same values.This is my replace function:int replaceText(char *findWhat, char *replaceWith, BOOL bWholeWord, BOOL bMatchCase, BOOL bSearchDown) { CHARRANGE cr; int foundText = 0; SendMessage(g_hRichEdit, EM_EXGETSEL, 0, (LPARAM) &cr); if (cr.cpMin == cr.cpMax) foundText = searchText(findWhat, bWholeWord, bMatchCase, bSearchDown); else { CHARRANGE crText; FINDTEXTEX ftex; ftex.chrg = cr; ftex.chrgText = crText; ftex.lpstrText = findWhat; SendMessage(g_hRichEdit, EM_FINDTEXTEX, 0, (LPARAM) &ftex); if (ftex.chrgText.cpMin == cr.cpMin && ftex.chrgText.cpMax == cr.cpMax) { MessageBox(NULL, "About to replace!", "Kladblok", MB_OK); SendMessage(g_hRichEdit, EM_REPLACESEL, TRUE, (LPARAM) replaceWith); } foundText = searchText(findWhat, bWholeWord, bMatchCase, bSearchDown); } return foundText;}The idea is that if nothing is selected, a search is made for the text so that the next time the function is called it will be selected. To be on the safe side, I do a search for the text within the selection to verify that it is indeed the string I want to replace. If that's the case, the CHARRANGE of the current selection and the one that has the search results should be the same.However, in practice, in both versions of the RichEdit control, cpMin of the selection is always lower by 2 (in my testcase of trying to replace 2 characters) than cpMin of the search result. The cpMax values are very high numbers. The strange thing is that with version 1 the replacement happens, but not with version 2, even though the values are the same and the condition should always be false. What's going on? Edited December 14, 2008 by BenoitRen
Mijzelf Posted December 15, 2008 Posted December 15, 2008 (edited) This is an ansi richedit? Does it reach the messagebox? Long shot: sometimes it helps to put a double 0 at the end of a string, when observing weird behaviour. Edited December 15, 2008 by Mijzelf
Recommended Posts
Please sign in to comment
You will be able to leave a comment after signing in
Sign In Now