Jump to content
Strawberry Orange Banana Lime Leaf Slate Sky Blueberry Grape Watermelon Chocolate Marble
Strawberry Orange Banana Lime Leaf Slate Sky Blueberry Grape Watermelon Chocolate Marble

MSFN is made available via donations, subscriptions and advertising revenue. The use of ad-blocking software hurts the site. Please disable ad-blocking software or set an exception for MSFN. Alternatively, register and become a site sponsor/subscriber and ads will be disabled automatically. 


Sign in to follow this  
BenoitRen

I want to make a Notepad alternative in C

Recommended Posts


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 by BenoitRen

Share this post


Link to post
Share on other sites

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 );

Share this post


Link to post
Share on other sites

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 by BenoitRen

Share this post


Link to post
Share on other sites

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 by BenoitRen

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites
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] = "";
#endif

Now 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.

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

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 by BenoitRen

Share this post


Link to post
Share on other sites

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 by Mijzelf

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...