Jump to content

I want to make a Notepad alternative in C


Recommended Posts

Yes, it's ANSI. At least until I can figure out how to properly support Unicode.

Does it reach the messagebox?

That's what I tried to explain. When I use RichEdit 1.0, it reaches it and replaces the string. With RichEdit 2.0, it doesn't. Yet the CHARRANGE members are the same!

Link to comment
Share on other sites


What shall I say? You must be mistaken. One of the if-statements have to evaluate differently. A debugger should be handy. You can add some tracing lines:

#include <stdarg.h>

void DoTrace( const char *format, ... )
{
 static char Buffer[ 512 ];
 va_list ap;
 va_start( ap, Format );
 _vsnprintf( Buffer, sizeof( Buffer ), Format, ap );
 OutputDebugString( Buffer );
 va_end( ap );
}

#ifdef _DEBUG
# define TRACE DoTrace
#else
# define TRACE //
#endif

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);
 
TRACE( "(%u): cr.cpMin == cr.cpMax => %u\n", __LINE__, cr.cpMin == cr.cpMax );
 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);
TRACE( "(%u): ftex.chrgText.cpMin == cr.cpMin && ftex.chrgText.cpMax == cr.cpMax => %u\n", __LINE__, ftex.chrgText.cpMin == cr.cpMin && ftex.chrgText.cpMax == cr.cpMax );
  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;
}

You can catch the output of OutputDebugString with DebugView, which is a tool from SysInternals. Alas Mark Russinovich is dumping all W9x support from his tools, but happily the old versions are still available at archive.org: http://web.archive.org/web/20050105011752/...debugview.shtml. (BTW, _vsnprintf is an MS function. You'll have to find the Borland equivalent.)

Link to comment
Share on other sites

I've tried to use Turbo Debugger 5.5. Every time I enter a character into the RichEdit it whines "Stopped on exception throw" and shows me a wall of assembly. Right-clicking on it reveals a menu with one of the choices being "Show source code", but it doesn't do anything.

I've tried tracing through it, but I haven't figured out how to make it trace immediately after inputting a character.

Link to comment
Share on other sites

You should compile your software using the '-v' option. Then you should have a sourcelevel debugger. About the execeptions, maybe you should change something in the 'Options->Exceptions' settings. The debugger should ignore the exceptions, and if it can't/won't, you should be able to push 'F9' in order to let the program continue to the breakpoint.

Link to comment
Share on other sites

I tried all that already.

It was compiled with the -v option (otherwise it would say it didn't have memory to load the symbol table). I tried fiddling with the Exception settings, but if it wasn't "stopped on exception throw", it was an error about accessing memory it shouldn't.

I tried again, and it's a little better about the exceptions this time. Placed a watch on ftex and cr, and put a breakpoint at the if statement. Looks like the assembler I was seeing is Windows code, not part of my executable.

cr: struct _charrange {11, 13}

ftex: struct _findtextexa {{11, 13}, :0040CE64, {-1, -1}}

Hmm. The range where the text is found is {-1, -1}.

Now with RichEdit 1.0. Strangely enough, it didn't raise any exceptions this time.

cr: struct _charrange {12, 14}

ftex: struct _findtextexa {{12, 14}, :0040CE60, {12, 14}}

Looks like a bug with RichEdit 3.0, because if different text is selected, the struct containing information about the find operation is also {-1, -1}.

Edited by BenoitRen
Link to comment
Share on other sites

  • 6 months later...

Wow, it's been a half year since I posted in this thread. I've made some small changes since then to have my program behave more normally, but nothing major. I did find out how to enable the opening of large files, though. Which leads me to the current problem that's been bugging me for some time...

I can't save large files. It gives an error. So I finally investigated using GetLastError() and FormatMessage(), and it turns out that the buffer I'm allocating it too small. I'm not sure why. A DWORD is 32-bit, which should be able to have a number as large as 2 GB, no? Anyway, this is the function I use to save a file, slightly altered from theForger's Win32 API Tutorial:

BOOL saveFile(LPCTSTR pszFileName) {
HANDLE hFile;
BOOL bSuccess = FALSE;
hFile = CreateFile(pszFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile != INVALID_HANDLE_VALUE) {
DWORD dwTextLength;
dwTextLength = GetWindowTextLength(g_hRichEdit);
if (dwTextLength > 0) {
LPSTR pszText;
DWORD dwBufferSize = dwTextLength + 1;
pszText = GlobalAlloc(GPTR, dwBufferSize);
if (pszText != NULL) {
if (GetWindowText(g_hRichEdit, pszText, dwBufferSize)) {
DWORD dwWritten;
if (WriteFile(hFile, pszText, dwTextLength, &dwWritten, NULL)) {
bSuccess = TRUE;
}
}
GlobalFree(pszText);
}
}
}
return bSuccess;
}

Despite previous Google searches being fruitless, I decided to try again. This time a message board thread suggested a solution. I looked at the EM_STREAMOUT message, and from there figured out how to make a callback function and correct my file saving function. It now works great. :)

Edited by BenoitRen
Link to comment
Share on other sites

A DWORD is 32-bit, which should be able to have a number as large as 2 GB, no?
No. Strictly spoken a DWORD is unsigned, and thus can contain a number as large as 4GB.
So I finally investigated using GetLastError() and FormatMessage(), and it turns out that the buffer I'm allocating it too small. I'm not sure why.
The documentation of GetWindowText() says ' GetWindowText causes a WM_GETTEXT message to be sent to the specified window or control'. Reading further in the documentation of WM_GETTEXT: 'Rich Edit: If the text to be copied exceeds 64K, use either the EM_STREAMOUT or EM_GETSELTEXT message.'

So it's not explicitely stated that GetWindowText() won't work, but it's at least discouraged to try it.

Anf you did already find the suggested solution.

BTW, the documentation of GetWindowTextLength() states that the returnvalue can be bigger than the actual size. So in your code you should use the returnvalue of GetWindowText() to determine the actual size.

Link to comment
Share on other sites

There's another problem that I'd like to fix. When I do a Replace All operation, the control scrolls to each instance of the text in the file before replacing it. The scrolling happens automatically when the EM_EXSETSEL message is sent. This slows the replacing operating a lot.

I've looked for other ways to replace text, but I haven't found anything. There doesn't seem to be a way to prevent the implicit scrolling either.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...