Hi All,
Can anyone suggest a compact list of the basic API calls containing a usable synopsis of what they do.
I have a project which is console based but which I need to change to using the full GDI. However none of the window classes I have looked at come anywhere near to doing this. All I want to be able to do, at this stage, is to take keyboard input, echo it to the screen so I can see what I type and then send it to the core of my program which will process it and send output to the screen as and when necessary.
With the console I just need to read StdIn and write to StdOut.
With the full GDI I can't find a window which enable me to do this. In order to have CR - LF and backspaces handled I seem to need some form of edit control only these don't let me get at the characters to process them. To do this I can trap and process WM_CHAR only now the CRs LFs and backspaces are not done. Also it is by no means clear to me which windows generate the WM_CHAR message.
Output is even worse. According to some well known tutorials I need to put all the code that creates output into the WM_PAINT handler. However this code takes input which is also echoed to the output.... This begins to look dangerously like a recursive Kline Bottle!
Regards Roger
Graphical interfaces generally require a different form of planning to consoles. They are different because they are used for different things and in different ways. Trying to force a console program into a GUI is not likely to go well.
If you use existing controls there is no need to handle most messages, generally WM_COMMAND is sufficient. Have a look at the MASM32 examples and Iczelion's tutorials to get into this - it is not a straightforward transition from console to GUI.
Having said that, what you may be after is similar to a lot of IRC clients (or other chat programs). Having a look at some of these may help you get an understanding of how your own program will work in a non-console environment.
Cheers,
Zooba :U
Zooba,
Thank you for your reply.
I have looked at MASM32's examples and studied Iczilion. However Iczilion's tutorials stop when it gets interesting, they don't show how to grow snippets into programs. For example take his tutorial 6 on keyboard input; He shows how to read a character onto the screen - just one character because the next one overwrites it. What he doesn't tell us is which windows/controls/styles to select to show whole words or even complete lines of text. Yes I can work out how to handle the formating characters, build a page and make it scroll but this is work the GUI is supposed to do for me.
I tried finding an IRC Client or similar but I could only find code for console apps which did not help.
My problem is not making the program fit the GUI, it is in finding the API calls which will do what I want without having to spend to much time reinventing wheels. Thus my original question:-
Can anyone suggest a compact list of the basic API calls containing a usable synopsis of what they do?
Regards Roger.
Of course if anyone knows a really good wheelwright....
Roger,
You will come close to an IRC interface by creating a Window and using an edit control in its client area. The trick with the edit control is to have one large multiline one for display and a single line one under it for text entry. The data typed into the lower single line edit control is then appended to the end of the text in the main display edit control above it.
Hi Roger:
I would venture to say anything involving windows precludes the word synopsis. There are just too many variables and combinations to even begin. Sub or Super classing text boxes is one way of catching WM_CHAR and you can even have your child windows pass events to parent window first so you could catch and ESC character no matter how many controls you have in the parent. Then for application defined windows such as the main window, if WM_PAINT is designed properly you can lose data when another window covers yours or get severe screen flicker.
If you are able to share your code or at least snippets of it I can probably help you out with specific details, then others can learn by these examples, or maybe even sugges better ways, especially as it's related to taking a console app and converting to GUI.
Peter
Quote from: Roger on September 24, 2008, 11:30:26 AM
Iczilion's tutorials stop when it gets interesting, they don't show how to grow snippets into programs. ... What he doesn't tell us is which windows/controls/styles to select to show whole words or even complete lines of text.
That's because they're tutorials, and this is where the MASM32 examples come in. Iczilion tutorials 9, 18, 19 and 24 (and probably more, but I've only had a quick look) involve creating various controls that you may find useful. There are MASM32 examples showing which messages are involved with these, and you can always experiment with styles.
Quote from: Roger on September 24, 2008, 11:30:26 AM
I tried finding an IRC Client or similar but I could only find code for console apps which did not help.
Code is less important than knowing what controls you want. The examples showing lots of controls are for you to learn the names of them, so you can identify an edit box, a tree view, a combo box and a button (and the rest :wink ). Each of these are provided by the operating system, and creating and using them is demonstrated in the examples. I suggested an IRC client because it's the sort of fake-console interface you were talking about.
If you want a "quick-reference" guide (of sorts), the list of Windows Controls (http://msdn.microsoft.com/en-us/library/bb773173(VS.85).aspx) at MSDN is probably your best bet. How helpful it will be I don't know, but good luck.
Cheers,
Zooba :U
Roger,
If you do not want to show us your sources at least attach the executable so we can get an idea of what you want. If you are looking for a console like environment that allows you to run code as well as type text, I have a program called WinConsole that might help you. It is the standalone proof of concept that I used to add this ability to my editor. I have alwways kept it, just in case I needed something like that again. Parts of that program came courtesy of Zcoder.
But, right now, you have typed a lot of words and we aree basically clueless as to what you want unless it is a chat engine you want to create.
-- Paul
Hi
Quote from: hutch-- on September 24, 2008, 11:41:37 AM
The trick with the edit control is to have one large multiline one for display and a single line one under it for text entry. The data typed into the lower single line edit control is then appended to the end of the text in the main display edit control above it.
I like the look of this and I must try it out next.
I have attached some code.
'Serial1' is adapted from an old console mode program I use to connect to an embedded microprocessor. When it is working I want to add a Forth engine to share some of the work the microprocessor has to do.
Linked as a console program it seems to work still but the display to the window is haywire. As a Gui without a console I do not get enough info to tell if it is working.
Regards Roger
BTW I would have posted it earlier but the m/c I am developing it on does not have internet access and transferring it over took longer than expected.
[attachment deleted by admin]
Quote from: Roger on September 26, 2008, 07:33:40 PMAs a Gui without a console I do not get enough info to tell if it is working.
You can't mix console methods with GUI, so wherever you're using "print", replace with MesssageBox.
.const
Caption db 'INITIALIZATION FAILURE', 0
Text db 'Serial Failed', 0
.code
invoke MessageBox, hWnd, ADDR Text, ADDR Caption, MB_ICONINFORMATION
See documentation on this API for more detail
Quote from: Tight_Coder_Ex on September 26, 2008, 08:44:56 PM
You can't mix console methods with GUI, so wherever you're using "print", replace with MesssageBox.
include \masm32\include\masm32rt.inc
.code
AppName db "Masm32:", 0
start: print "You can mix console output and message boxes"
MsgBox 0, "Hello World", addr AppName, MB_OK
exit
end start
Hi,
Quote from: Tight_Coder_Ex on September 26, 2008, 08:44:56 PMinvoke MessageBox, hWnd, ADDR Text, ADDR Caption, MB_ICONINFORMATION
Thank you, This does help!
However I am still unable to find the information I need and the more I read the more contradictions I seem to discover.
Take the code below:-
I have commented out the WM_PAINT and WM_CHAR sections (but not the invoke MessageBox Lines). Now I expected that this would stop any text reaching the window but it didn't, the keyboard text appears. Remove (comment out) the WM_SIZE section and now the keyboard text goes but the window can still be moved.
Alternatively put the WM_PAINT and WM_CHAR sections in (without the invoke MessageBox lines) and leave the WM_SIZE section out and the string text appears. However either the WM_SECTION or one of the MessageBox lines is needed for keyboard text to be written.
It would seem to me that responding to WM_SIZE messages is having effects other than resizing the window yet is not needed to re-size the window as that is done by DefWindowProc.
I notice that DrawText does not recognise CR-LFs whereas ShowText does, yet I can't find reference to this difference in the platform SDK.
Quote from: hutch-- on September 24, 2008, 11:41:37 AM
The trick with the edit control is to have one large multiline one for display and a single line one under it for text entry. The data typed into the lower single line edit control is then appended to the end of the text in the main display edit control above it.
I have tried this but I can't get the two controls in the same window to work differently - at least not in the way I expect.
Confused Regards Roger
.386
.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\gdi32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\gdi32.lib
WinMain PROTO :DWORD,:DWORD,:DWORD,:DWORD
; -------------------------------------------------------------------------
.data
ClassName db "WindClass",0
AppName db "Text Window",0
EditClass db "EDIT",0
TestStg1 db " 1 Test string 1 ",0Ah,0Dh, "Next Line",0
TestStg2 db " 2 Test string 2 ",0
TestStg3 db " 3 Test string 3 ",0
MesgStg1 db " WM_PAINT ",0
MesgStg2 db " WM_CHAR ",0
MesgStg3 db " WM_SIZE ",0
Caption db 'Message', 0
char WPARAM 41h ; the character the program receives from keyboard
pointer DD 0 ; pointer to move char about
; -------------------------------------------------------------------------
.data?
hInstance HINSTANCE ?
hwndEdit dd ?
CommandLine LPSTR ?
hwnd DD ?
; -------------------------------------------------------------------------
.code
start:
invoke GetModuleHandle, NULL
mov hInstance,eax
invoke WinMain, hInstance,NULL,NULL, SW_SHOWDEFAULT
invoke ExitProcess,eax
; -------------------------------------------------------------------------
WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
LOCAL wc:WNDCLASSEX
LOCAL msg:MSG
; LOCAL hwnd:HWND
mov wc.cbSize,SIZEOF WNDCLASSEX
mov wc.style, CS_HREDRAW or CS_VREDRAW
mov wc.lpfnWndProc, OFFSET WndProc
mov wc.cbClsExtra,NULL
mov wc.cbWndExtra,NULL
push hInst
pop wc.hInstance
mov wc.hbrBackground,COLOR_WINDOW+1
mov wc.lpszMenuName,NULL
mov wc.lpszClassName,OFFSET ClassName
invoke LoadIcon,NULL,IDI_APPLICATION
mov wc.hIcon,eax
mov wc.hIconSm,0
invoke LoadCursor,NULL,IDC_ARROW
mov wc.hCursor,eax
invoke RegisterClassEx, addr wc
invoke CreateWindowEx,WS_EX_CLIENTEDGE,ADDR ClassName,ADDR AppName,\
WS_OVERLAPPEDWINDOW+WS_VISIBLE,\
300,300, 600,400, NULL,NULL,hInst,NULL
mov hwnd,eax
x1: invoke GetMessage, ADDR msg,NULL,0,0
or eax,eax
jz x2
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
jmp x1
x2: mov eax,msg.wParam
ret
WinMain endp
; -------------------------------------------------------------------------
WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
LOCAL hdc:HDC
LOCAL ps:PAINTSTRUCT
LOCAL rect:RECT
.IF uMsg==WM_DESTROY
invoke PostQuitMessage,NULL
.ELSEIF uMsg==WM_CREATE
invoke CreateWindowEx,NULL,addr EditClass,NULL,\
WS_CHILD+WS_VISIBLE+ES_MULTILINE+ES_AUTOHSCROLL+ES_AUTOVSCROLL,\
0,0,0,0,hWnd,NULL,hInstance,NULL
mov hwndEdit,eax
push eax
call SetFocus
; .ELSEIF uMsg==WM_SIZE ; seems to paint window
; mov edx,lParam
; mov ecx,edx
; shr ecx,16
; and edx,0ffffh
; invoke MoveWindow,hwndEdit,0,0,edx,ecx,TRUE
invoke MessageBox, NULL, ADDR MesgStg3, ADDR Caption, MB_ICONINFORMATION
; call SetFocus
; .ELSEIF uMsg==WM_PAINT
; invoke BeginPaint,hWnd, ADDR ps
; mov hdc,eax
; invoke GetClientRect,hWnd, ADDR rect
; invoke DrawText, hdc,ADDR TestStg1,SIZEOF TestStg1, ADDR rect, DT_EDITCONTROL+DT_WORDBREAK
; inc [rect.top]
; invoke DrawText, hdc,ADDR TestStg2,10, ADDR rect, DT_EDITCONTROL+DT_WORDBREAK
; mov eax,[pointer] ; Move the position of the character
; inc eax
; mov [pointer],eax
; imul eax,8
; invoke TextOut,hdc,eax,48,ADDR char,1
invoke MessageBox, NULL, ADDR MesgStg1, ADDR Caption, MB_ICONINFORMATION
; invoke SetBkColor,hdc,0ffFFh
; invoke TextOut,hdc,300,0,ADDR TestStg1,SIZEOF TestStg1
; invoke EndPaint,hWnd, ADDR ps
; .ELSEIF uMsg==WM_CHAR
; push wParam
; pop char
; invoke [SendMessage], [hwndEdit], EM_REPLACESEL, 0, offset char
;
invoke MessageBox, NULL, ADDR MesgStg2, ADDR Caption, MB_ICONINFORMATION
; invoke InvalidateRect, hWnd,NULL,TRUE
.ELSE
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.ENDIF
xor eax,eax
ret
WndProc endp
; -------------------------------------------------------------------------
end start
Me confused, too. What do these message boxes in the middle of nowhere? Delete the commented lines to see what you really have coded. There is one clear bug:
.ELSEIF uMsg==WM_SIZE ; seems to paint window
mov edx,lParam
mov ecx,edx
shr ecx,16
and edx,0ffffh
invoke MoveWindow,hwndEdit,0,0,edx,ecx,TRUE
; invoke MessageBox, NULL, ADDR MesgStg3, ADDR Caption, MB_ICONINFORMATION
call SetFocus
No parameters supplied! This would not have happened if you use
invoke SetFocus, hwndEdit
When commenting out SetFocus, I get a window that has an edit field that behaves entirely as expected. And still I have no idea what you want to achieve...
Quote from: jj2007 on October 02, 2008, 11:25:13 PM
What do these message boxes in the middle of nowhere? Delete the commented lines to see what you really have coded.
I put them there to try to see when the particular WM_?? messages where occurring.
EDIT
I was under the impression that WM_CHAR was the method of obtaining keyboard text and WM_PAINT was the method of displaying it. I found that some code I had was not sending these messages so I extracted just the bit you see to try and find out what was happening.
The message boxes best left commented out most of the time.
Quote
There is one clear bug:
call SetFocus
No parameters supplied!
I corrected that. I could see no improvement!
Quote
When commenting out SetFocus, I get a window that has an edit field that behaves entirely as expected.
Try it with everything in and then with the WM_SIZE code commented out. Which of these did you expect to happen or did you expect the WM_SIZE code to actually make that difference?
Quote
And still I have no idea what you want to achieve...
What I want to achieve is understanding what is happening when I use API calls. In the interim I would like a window which handles Keyboard and other text in a similar way to the console.
Regards Roger
Quote from: Roger on October 03, 2008, 10:35:34 AM
Try it with everything in and then with the WM_SIZE code commented out. Which of these did you expect to happen or did you expect the WM_SIZE code to actually make that difference?
Your WM_SIZE handler does not
paint the edit box - it
sizes it. Without it, your box remains at the 0,0,0,0 that you assigned in the CreateWindowEx call...
Quote from: jj2007 on October 03, 2008, 12:08:21 PM
Quote from: Roger on October 03, 2008, 10:35:34 AM
Try it with everything in and then with the WM_SIZE code commented out. Which of these did you expect to happen or did you expect the WM_SIZE code to actually make that difference?
Your WM_SIZE handler does not paint the edit box - it sizes it. Without it, your box remains at the 0,0,0,0 that you assigned in the CreateWindowEx call...
When I run it with the WM_SIZE handler in I get only the keyboard text and none of the string text.
When I run it with the WM_SIZE handler commented out I get only the string text and no keyboard text.
If I then minimize the window and the restore it I get single characters from the keyboard
If I alter the size of the window (with my mouse) it still gets re-sized and the single keyboard character rapidly exits stage left. (Presumably this is done by DefWindowProc sending repeated WM_PAINT messages and my WM_PAINT handler incrementing the pointer.)
If I minimize and restore the window after I have re-sized it, then I don't get single keyboard characters.
My WM_SIZE handler may not
paint the edit box but it does a lot more than
sizing it.
Regards Roger
Quote from: Roger on October 03, 2008, 01:38:08 PM
My WM_SIZE handler may not paint the edit box but it does a lot more than sizing it.
It sizes the edit box. All the other actions are being done by other messages that you don't (and don't need to) capture. Please activate the WM_SIZE handler, and nothing else. You need two small changes:
TestStg1 db " 1 Test string 1 ", 0Dh, 0Ah, "Next Line", 0
mov hwndEdit,eax
invoke SetFocus, eax
invoke SendMessage, hwndEdit, WM_SETTEXT, 0, addr TestStg1
invoke SendMessage, hwndEdit, EM_SETSEL, 0ffffh, 0ffffh
Quote from: jj2007 on October 03, 2008, 02:29:07 PM
[ All the other actions are being done by other messages that you don't (and don't need to) capture. Please activate the WM_SIZE handler, and nothing else.
But I do need to do them.
TestStg! is only a test. The project will have several strings which will be selected at runtime so they cannot be in the WM_CREATE handler but need to be in the WM_PAINT handler - unless someone knows a better place for them.
I had this in the WM_PAINT handler
invoke SetBkColor,hdc,0ffFFh
invoke TextOut,hdc,300,0,ADDR TestStg1,SIZEOF TestStg1
I need WM_CHAR to capture keystrokes for parsing and sending elsewhere apart from the display.
Quote
TestStg1 db " 1 Test string 1 ", 0Dh, 0Ah, "Next Line", 0
Isn't Windows fussy! and it still doesn't work for DrawText
Regards Roger
Quote from: Roger on October 03, 2008, 04:42:35 PM
Isn't Windows fussy! and it still doesn't work for DrawText
Indeed! DrawText will break lines but does not accept manual CrLfs. TextOut is the only solution afaik. I have worked a lot with these functions but under Win 3.1, so I don't dare to give advice...
It is easier (and more reliable) to process keystrokes directly in the message loop using the WM_KEYUP and/or WM_KEYDOWN messages as follows:
.if msg.message == WM_KEYUP
invoke GetAsyncKeyState, VK_CONTROL
rol eax, 16
cmp ax, 1111111111111111b
jne ProcessMessage
.if msg.wParam == 46h ; Ctrl + F
invoke SendMessage, hWnd, WM_COMMAND, IDM_FIND, 0
jmp StartLoop
.elseif ...
For me, Control keys process betterin the WM_KEYUP area and Funtion keys process better in the WM_KEYDOWN area. Some will say it does not matter, just do what works for you.
Do this instead of using WM_CHAR. WM_CHAR has problems with certain key combinations and will not handle a CRLF pair at all. It is beyond the scope of the message's capabilities.
-- Paul