Log in

View Full Version : Append text to an edit control text buffer?


homersux
August 5th, 2004, 18:33
Other than getwindowtext, append text, then setwindowtext, is there a easy way to append text
to a multi-line edit control? This could be used as a convenient log window for verbose information output.

Kayaker
August 5th, 2004, 21:53
Hi,

Are you meaning in your own code, as opposed to this is a reversing trick question?

Unless you WANT to use a multiline edit control, using a listbox and LB_ADDSTRING might be a bit more convenient for log output like this. It's dead easy to control, add, modify... Also has the nice feature of being able to associate a dword value to any item you add using LB_SETITEMDATA, for whatever use you might make of that.

Unless you go to RichEdit, multiline edit controls somehow don't seem as useful for *appending* text without having to fiddle around with carets, line breaks, scrolling and such. Assuming you don't want user input you could use WM_SETTEXT, but it seems you'd need to copy the existing text to a buffer, append it, then write it back, too much overhead.

I find listboxes handy for displaying results from GetLastError / FormatMessage output, which I try to use routinely. Not that this has anything to do with your question, but for the sake of code an example and couple of macros:

Code:

...
.else ; CreateService fails

invoke GetLastError
; most likely error is ERROR_SERVICE_EXISTS equ 431h

OutputLBText hListBox_Log, \
CTEXT("ERROR: CreateService failed with System Message:"

OutputSystemErrorMsg hListBox_Log

.endif ; CreateService endif


;=======================================================
; Listbox handling Macros to deal with display issues
;=======================================================

;--------------------------------------------------------------------
; MACRO to format FormatMessage string for display in Listbox
; CarriageFeed/LineReturn is not handled well by Listboxes.
; This macro finds the CF/LR added by FormatMessage and
; null terminates the string.
; Usage: pass system error message in eax, i.e.
; invoke GetLastError
; OutputSystemErrorMsg, hListBox
;--------------------------------------------------------------------
OutputSystemErrorMsg MACRO _hWnd
LOCAL lpFormatMsg
.data?
lpFormatMsg db 64 dup(?) ; max buffer for FormatMessage
.code
invoke FormatMessage, FORMAT_MESSAGE_FROM_SYSTEM, NULL, eax,\
NULL, offset lpFormatMsg, sizeof lpFormatMsg, NULL

cld
push ecx
push edi
mov eax, 0Dh
or ecx, -1
lea edi, offset lpFormatMsg
repne scasb
dec edi
mov byte ptr [edi], 0 ; null terminate the string
pop edi
pop ecx

invoke SendMessage, _hWnd, LB_ADDSTRING, 0, offset lpFormatMsg
invoke SendMessage, _hWnd, LB_ADDSTRING, 0, CTEXT(" "
invoke SendMessage, _hWnd, LB_GETCOUNT, 0, 0
sub eax, 1
invoke SendMessage, _hWnd, LB_SETTOPINDEX, eax, 0
ENDM
;--------------------------------------------------------------------

;--------------------------------------------------------------------
; MACRO to output Listbox text, may include CF/LR and/or variable formatting arguments
; Usage: pass CF/LR as "\n", leave blank if desired if including Args
; OutputLBText hWnd, CTEXT("text"
; OutputLBText hWnd, CTEXT("text", \n
; OutputLBText hWnd, CTEXT("text %04X", \n, eax
; OutputLBText hWnd, CTEXT("text %04X %04d", ,eax, eax
;--------------------------------------------------------------------
OutputLBText MACRO _hWnd, Text, CFLR, Args:VARARG
LOCAL StringBuff
.data?
StringBuff db MAX_PATH dup(?)
.code
push eax
IFNB <Args> ; if 'Args' argument is not blank, format according to Text syntax
invoke wsprintf, offset StringBuff, Text, Args
invoke SendMessage, _hWnd, LB_ADDSTRING, 0,\
offset StringBuff
IFNB <CFLR> ; if 'CFLR' argument is not blank, add a blank line
invoke SendMessage, _hWnd, LB_ADDSTRING, 0, CTEXT(" "
ENDIF
ENDIF

IFB <Args> ; if 'Args' argument is blank, output Text as passed
invoke SendMessage, _hWnd, LB_ADDSTRING, 0, Text
IFNB <CFLR>
invoke SendMessage, _hWnd, LB_ADDSTRING, 0, CTEXT(" "
ENDIF
ENDIF
invoke SendMessage, _hWnd, LB_GETCOUNT, 0, 0
sub eax, 1
invoke SendMessage, _hWnd, LB_SETTOPINDEX, eax, 0

pop eax
ENDM
;--------------------------------------------------------------------
;=======================================================


Kayaker

homersux
August 6th, 2004, 08:26
well unfortunately, i need to use a simple logging edit control in user land app.
The problem with list control is it cannot be easily copy/pasted. RichEdit is not
a basic gdi32 control object. I may have to fall back to the copy/append/reset
approach since the amount of text information is not huge.

cr.ap
August 6th, 2004, 19:58
according to msdn you can get/set a handle to the EditControl TextBuffer with EM_GETHANDLE/EM_SETHANDLE, however last time i played with it for the exact same reason, i couldnt get it to work correctly an do so dianlly ended up with the same old circular buffer and Get/SetWindowText, maybe you have more luck.

cr.ap

PS: another option for appending may be EM_SETSEL/EM_REPLACESEL.