News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

How to Use Streams

Started by six_L, June 17, 2019, 01:13:14 AM

Previous topic - Next topic

six_L

DWORD CALLBACK EditStreamCallback(DWORD_PTR dwCookie,
                                  LPBYTE lpBuff,
                                  LONG cb,
                                  PLONG pcb)
{
    HANDLE hFile = (HANDLE)dwCookie;
   
    if (ReadFile(hFile, lpBuff, cb, (DWORD *)pcb, NULL))
    {
        return 0;
    }
   
    return -1;
}

BOOL FillRichEditFromFile(HWND hwnd, LPCTSTR pszFile)
{
    BOOL fSuccess = FALSE;
   
    HANDLE hFile = CreateFile(pszFile, GENERIC_READ,
                              FILE_SHARE_READ, 0, OPEN_EXISTING,
                              FILE_FLAG_SEQUENTIAL_SCAN, NULL);
       
    if (hFile != INVALID_HANDLE_VALUE)
    {
        EDITSTREAM es = { 0 };
       
        es.pfnCallback = EditStreamCallback;
        es.dwCookie    = (DWORD_PTR)hFile;
       
        if (SendMessage(hwnd, EM_STREAMIN, SF_RTF, (LPARAM)&es) && es.dwError == 0)
        {
                fSuccess = TRUE;
        }
       
        CloseHandle(hFile);
    }
   
    return fSuccess;
   
}

on here code example,is the lpBuff created by OS ?
Say you, Say me, Say the codes together for ever.

jj2007

Yes. On Win7-64, it's a 4k buffer, and it receives 4092 bytes for every read in the callback function:
StreamInProc proc hFile, pBuffer, NumBytes, pBytesRead
  invoke ReadFile, hFile, pBuffer, NumBytes, pBytesRead, 0
  xor eax, 1
  ret
StreamInProc endp

Tedd

The RichEdit control allocates that memory as needed, and then sends you a pointer (lpBuff) so you can give it a chunk of data; you don't need to worry about allocating/freeing it.
Potato2

six_L

hi,jj2007,Tedd
Thanks your help.
test it crashed.
EditStreamCallback(DWORD_PTR dwCookie,
                                  LPBYTE lpBuff,
                                  LONG cb,
                                  PLONG pcb)
{

EditStreamCallback proc dwCookie:DWORD,lpBuff:QWORD,cb:QWORD,pcb:QWORD
in X64,HANDLE->QWORD.
"HANDLE hFile = (HANDLE)dwCookie", is it aright?
Say you, Say me, Say the codes together for ever.

aw27

Editstreamcallback proc dwCookiw:PTR, ptBuff:PTR, cb:DWORD, pcb:PTR


DWORD_PTR is not DWORD in 64-bit.

six_L

#5
the following code is always crashed.
option casemap:none
option win64:3
;¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
include \UASM64\include\windows.inc
include \UASM64\include\CommCtrl.inc
include \UASM64\include\Richedit.inc

includelib \UASM64\Lib\kernel32.lib
includelib \UASM64\Lib\user32.lib
includelib \UASM64\Lib\comctl32.lib
includelib \UASM64\Lib\comdlg32.lib
includelib \UASM64\Lib\gdi32.lib
;¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
ICO_MAIN equ 1000h
IDM_MAIN equ 2000h
IDM_OPEN equ 4101h
;¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
.data

;¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
.data?
hInstance qword ?
hWinMain qword ?
hMenu qword ?
hWinEdit qword ?
g_hFile qword ?
@hRichEditDLL qword ?
@stES EDITSTREAM <?>
;¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
.const
szDllEdit db "RichEd20.dll",0
szClassEdit db "RichEdit20A",0
;¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
.code
;¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
StreamInProc proc dwCookiw:PTR, ptBuff:PTR, cb:DWORD, pcb:PTR

invoke ReadFile,dwCookiw,ptBuff,cb,pcb,0
xor rax,TRUE
ret

StreamInProc endp
;¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
ErrorMessage Proc uses rbx lpCaption:qword
Local lpErrorMessage:qWORD

call GetLastError
lea rbx,lpErrorMessage
invoke FormatMessage, FORMAT_MESSAGE_ALLOCATE_BUFFER or FORMAT_MESSAGE_FROM_SYSTEM, NULL, eax, LANG_NEUTRAL,rbx,0,NULL

invoke MessageBox, 0, lpErrorMessage, lpCaption, MB_OK or MB_ICONINFORMATION
invoke LocalFree, lpErrorMessage
ret   

ErrorMessage EndP
;¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
_OpenFile proc _hWnd:QWORD
local @FileNamePath[MAX_PATH]:BYTE
local ofn:OPENFILENAME


invoke RtlZeroMemory, addr @FileNamePath, sizeof @FileNamePath
invoke RtlZeroMemory, addr ofn, sizeof ofn

mov eax,sizeof ofn
mov ofn.lStructSize,eax

mov rax,_hWnd
mov ofn.hwndOwner,rax

mov rax,CStr("All Files (*.*)",0,"*.*",0,0)
mov ofn.lpstrFilter,rax

mov ofn.nMaxFile,MAX_PATH

mov rax,CStr("Get the Name and Path.")
mov ofn.lpstrTitle,rax

mov rax,hInstance
mov ofn.hInstance,rax

lea rax,@FileNamePath
mov ofn.lpstrFile,rax
;int 3

invoke GetOpenFileName,addr ofn
;INT 3
invoke SetWindowText,_hWnd,addr @FileNamePath
invoke CreateFile,addr @FileNamePath,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0
.if eax==-1 ;cant read file
invoke ErrorMessage,CStr("CreateFile")
xor rax,rax
ret
.endif

mov g_hFile,rax

invoke RtlZeroMemory, addr @stES, sizeof @stES
mov rax,g_hFile
mov @stES.dwCookie,rax
lea rax,StreamInProc
mov @stES.pfnCallback,rax
mov @stES.dwError,NULL

invoke SendMessage,hWinEdit,EM_STREAMIN,SF_TEXT,addr @stES
invoke CloseHandle,g_hFile
    mov rax,TRUE
@ErrExit:       

ret
_OpenFile endp
;¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
_ProcWinMain proc hWnd:qword,uMsg:dword,wParam:qword,lParam:qword
local @Edit_Rt:RECT
LOCAL @rsi:QWORD
LOCAL @rdi:QWORD

mov eax,uMsg
.if eax == WM_CREATE
invoke CreateWindowEx,WS_EX_CLIENTEDGE,offset szClassEdit,NULL,\
ES_LEFT + ES_MULTILINE + ES_AUTOVSCROLL + ES_AUTOHSCROLL + WS_VSCROLL + WS_HSCROLL \
+ WS_VISIBLE + WS_CHILD,0,0,404,123,\
hWnd,0,hInstance,NULL

mov hWinEdit,rax

.elseif eax == WM_COMMAND && wParam != 0
mov rax,wParam
.if ax == IDM_OPEN
invoke _OpenFile,hWnd
.endif
.elseif eax == WM_SIZE

invoke GetClientRect, hWnd, addr @Edit_Rt

mov @rsi, rsi
mov @rdi, rdi

mov esi,@Edit_Rt.bottom
sub esi,@Edit_Rt.top
mov edi,@Edit_Rt.right
sub edi,@Edit_Rt.left
invoke MoveWindow, hWinEdit,0, 0,edi,esi, TRUE

mov rsi,@rsi
mov rdi,@rdi

.elseif eax == WM_CLOSE
invoke DestroyWindow,hWinMain
invoke PostQuitMessage,NULL
.else
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.endif
xor rax,rax
ret

_ProcWinMain endp
;¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
_WinMain proc
local @stWndClass:WNDCLASSEX
local @stMsg:MSG

invoke GetModuleHandle,NULL
mov hInstance,rax
invoke LoadLibrary,offset szDllEdit
mov @hRichEditDLL,rax

invoke LoadMenu,hInstance,IDM_MAIN
mov hMenu,rax
invoke RtlZeroMemory,addr @stWndClass,sizeof @stWndClass
invoke LoadIcon,hInstance,ICO_MAIN
mov @stWndClass.hIcon,rax
mov @stWndClass.hIconSm,rax
invoke LoadCursor,0,IDC_ARROW
mov @stWndClass.hCursor,rax
push hInstance
pop @stWndClass.hInstance
mov @stWndClass.cbSize,sizeof WNDCLASSEX
mov @stWndClass.style,CS_HREDRAW or CS_VREDRAW
lea rax,_ProcWinMain
mov @stWndClass.lpfnWndProc,rax
mov @stWndClass.hbrBackground,COLOR_WINDOW + 1
mov rax,CStr("Test_Streams")
mov @stWndClass.lpszClassName,rax
invoke RegisterClassEx,addr @stWndClass
invoke CreateWindowEx,WS_EX_CLIENTEDGE,CStr("Test_Streams"),CStr("Test_Streams"),\
WS_OVERLAPPEDWINDOW,400,200,400,300,NULL,hMenu,hInstance,NULL
mov hWinMain,rax
invoke ShowWindow,hWinMain,SW_SHOWNORMAL
invoke UpdateWindow,hWinMain
.while TRUE
invoke GetMessage,addr @stMsg,NULL,0,0
.break .if rax == 0
invoke TranslateMessage,addr @stMsg
invoke DispatchMessage,addr @stMsg
.endw
invoke FreeLibrary,@hRichEditDLL
ret

_WinMain endp
;¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
WinMainCRTStartup Proc
invoke _WinMain
invoke ExitProcess,NULL
ret
WinMainCRTStartup Endp
;¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

end WinMainCRTStartup


#include <\UASM64\include\resource.h>
#define ICO_MAIN 0x1000
#define IDM_MAIN 0x2000
#define IDM_OPEN 0x4101
ICO_MAIN ICON "main.ico"
IDM_MAIN menu discardable
BEGIN
popup "File(&f)"
BEGIN
menuitem "Open(&o)...", IDM_OPEN
END
END

Say you, Say me, Say the codes together for ever.

aw27

It is interesting, even in 64-bit, EDITSTREAM should be 4-aligned not 8-aligned. This can be seen in the C/C++ richedit.h include file (#include <pshpack4.h>).

So, the structure should be:

EDITSTREAM   struct 4
dwCookie   DWORD_PTR   ?
dwError   DWORD   ?
pfnCallback   EDITSTREAMCALLBACK   ?
EDITSTREAM   ends

to prevent the crash.






six_L

QuoteEDITSTREAM should be 4-aligned not 8-aligned.
:thumbsup: :thumbsup: :thumbsup:
This is accurately the solution to the problem.
thank you very much.
Say you, Say me, Say the codes together for ever.