I have a nasty bug,so after a while it suddenly exits
I have gone for more readable code with LOCAL variables for a smoother way to solve it,afterwards
I have very little GDI experience, I am more ddraw experienced
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
TopXY proc wDim:DWORD, sDim:DWORD
shr sDim, 1 ; divide screen dimension by 2
shr wDim, 1 ; divide window dimension by 2
mov eax, wDim ; copy window dimension into eax
sub sDim, eax ; sub half win dimension from half screen dimension
return sDim
TopXY endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
Paint_Proc proc hWin:DWORD
LOCAL hDC :DWORD
LOCAL btn_hi :DWORD
LOCAL btn_lo :DWORD
LOCAL rect:RECT
LOCAL Rct :RECT
LOCAL Ps :PAINTSTRUCT
LOCAL sourcex :DWORD
LOCAL sourcey :DWORD
LOCAL destx :DWORD
LOCAL desty :DWORD
LOCAL color :DWORD
invoke BeginPaint,hWin,ADDR Ps
mov hDC, eax
; ----------------------------------------
;invoke GetSysColor,COLOR_BTNHIGHLIGHT
mov btn_hi, eax
;invoke GetSysColor,COLOR_BTNSHADOW
mov btn_lo, eax
mov edx,200
mov ecx,200
mov esi,310 ;X
mov edi,200 ;Y
mov eax,0
@@l5:
mov eax,0FFFFFFh
;mov eax,0
pushad
mov ecx,esi
mov edx,edi
sub edx,167
sub ecx,299
.IF pixelf==0
invoke GetPixel,hDC,sourcex,sourcey
.IF eax>300
sub eax,00FF00FFh
and eax,0FFFFFFh
.ENDIF
.ENDIF
.IF pixelf==0
mov edx,pixelp
;mov [pixelb+edx*4],eax
mov pixelf,0FFFFFFFFh
.ENDIF
invoke SetPixel,hDC,destx,desty,eax
popad
add esi,1
add eax,1
dec edx
jne @@l5
add edi,1
mov edx,200
sub esi,200
sub eax,200
add eax,256
dec ecx
jne @@l5
mov eax,0FFFFFFFFh
mov pixelf,eax
; ----------------------------------------
invoke EndPaint,hWin,ADDR Ps
ret
Paint_Proc endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start
you are doing a getpixel on a location you never set. other than that there are too many unset things like pixelf to test. can you post a working program to try?
Quote from: jimg on May 05, 2019, 02:56:56 AM
you are doing a getpixel on a location you never set. other than that there are too many unset things like pixelf to test. can you post a working program to try?
in the main part of program I have setup a richedit control and setText message and going from a getpixel/setpixel very slow move text from one area to another area,to only getpixel+store in a buffer once and set pixelf a flag so it only do getpixel in the loop once
maybe best to start a complete rewrite???
"bitmap must be selected within the device context, otherwise, CLR_INVALID is returned on all pixels."
ecx is not preserved before to call get/setpixel
it would be nice to have tiny code produce plenty bitmaps
to produce for example this:
and now tested a pic
so let GDI draw text on screen and get it to bitmap and stretchblt it would be lot easier
I am trying to change text on button when it gets pressed,with sendmessage WM_SETTEXT
but I am stuck with WM_COMMAND code that tries to change text???
and NULL background color its easier to make a GDI animation?
Try using WM_LBUTTONDOWN and WM_LBUTTONUP messages to make a custom control of that type.
Quote from: hutch-- on May 25, 2019, 12:09:56 PM
Try using WM_LBUTTONDOWN and WM_LBUTTONUP messages to make a custom control of that type.
trying to understand how you get ID for several buttons and settext on them and set images
but all WCHAR texts are loaded from resource for this windows program,this I want to load my own strings
I would appreciate a example
and trying to understand GDI better,I am more dx experienced and they can be combined to create things with GDI and read screen and use the faster dx
made some drawing code on ticalculator, I want to try with GDI
reading some tutorials
You can define the ID (resource id) of the button when you create it with CreateWindow (https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-createwindowa)/CreateWindowEx (https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-createwindowexa) or if its resource based you set the ID in the resource editor.
Once you have the ID you can get the handle of the button with GetDlgItem (https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-getdlgitem) (or the returned handle value from CreateWindow (https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-createwindowa)/CreateWindowEx (https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-createwindowexa))
Then you set the text for the button or other control with SetWindowText (https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-setwindowtexta) or via SendMessage (https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-sendmessage) and WM_SETTEXT (https://docs.microsoft.com/en-us/windows/desktop/winmsg/wm-settext)
For responding to the mouse click on the button you can use a button notification handled via WM_COMMAND (https://docs.microsoft.com/en-us/windows/desktop/menurc/wm-command) as BN_CLICKED (https://docs.microsoft.com/en-us/windows/desktop/controls/bn-clicked)
WndProc proc hWin:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
LOCAL wNotifyCode:DWORD
mov eax, uMsg
.IF eax == WM_INITDIALOG
; Init Stuff Here
.ELSEIF eax == WM_COMMAND
mov eax, wParam
shr eax, 16
mov wNotifyCode, eax
mov eax,wParam
and eax,0FFFFh
.IF eax == BUTTON1 ; button resource ID stored as a constant
.IF wNotifyCode == BN_CLICKED
; do something
.ENDIF
.ELSEIF eax == ... other ids, menus, toolbar buttons etc or other controls.
Quote from: fearless on May 25, 2019, 10:56:17 PM
You can define the ID (resource id) of the button when you create it with CreateWindow (https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-createwindowa)/CreateWindowEx (https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-createwindowexa) or if its resource based you set the ID in the resource editor.
Once you have the ID you can get the handle of the button with GetDlgItem (https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-getdlgitem) (or the returned handle value from CreateWindow (https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-createwindowa)/CreateWindowEx (https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-createwindowexa))
Then you set the text for the button or other control with SetWindowText (https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-setwindowtexta) or via SendMessage (https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-sendmessage) and WM_SETTEXT (https://docs.microsoft.com/en-us/windows/desktop/winmsg/wm-settext)
For responding to the mouse click on the button you can use a button notification handled via WM_COMMAND (https://docs.microsoft.com/en-us/windows/desktop/menurc/wm-command) as BN_CLICKED (https://docs.microsoft.com/en-us/windows/desktop/controls/bn-clicked)
WndProc proc hWin:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
LOCAL wNotifyCode:DWORD
mov eax, uMsg
.IF eax == WM_INITDIALOG
; Init Stuff Here
.ELSEIF eax == WM_COMMAND
mov eax, wParam
shr eax, 16
mov wNotifyCode, eax
mov eax,wParam
and eax,0FFFFh
.IF eax == BUTTON1 ; button resource ID stored as a constant
.IF wNotifyCode == BN_CLICKED
; do something
.ENDIF
.ELSEIF eax == ... other ids, menus, toolbar buttons etc or other controls.
thanks for example code,I am not used to resource editing,so I used Createwindow with several buttons and experimented,with try iconbutton,bitmap button but didnt work with send set image with small icon,checkbox version worked
what I try with clicked anykey is change text on button with sendmessage that says its been clicked
thats what I am after also,reuse buttons with different texts
I used some constants to the different buttons and tested with check for anykey is pressed the program exits and it works :eusa_clap:
sendmessage WM_SETTEXT works directly after buttoncreations placed right after the main window creation
sendmessage WM_SETTEXT fails inside wndproc,using a switch checking loword for B1 clicked in WM_COMMAND
handler
Post some code please so we can see where the issue is.
I am working on a mixed VC++/asm windows program,but at the same time getting more skilled in winapi is good for both masm and C++ skill
here it works to set another text,not work with set the small icon
buttontext is a WCHAR
// In this function, we save the instance handle in a global variable and
// create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
hInst = hInstance; // Store instance handle in our global variable
HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr);
HWND hwndButton = CreateWindow(
L"BUTTON", // Predefined class; Unicode assumed
L"THE ANY_KEY", // Button text
WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, // Styles
10, // x position
10, // y position
100, // Button width
100, // Button height
hWnd, // Parent window
(HMENU)B1, // No menu.
(HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE),
NULL); // Pointer not needed.
HWND hwndButton2 = CreateWindow(
L"BUTTON", // Predefined class; Unicode assumed
L"THE 2ND KEY", // Button text
BS_ICON | WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, // Styles
120, // x position
10, // y position
100, // Button width
100, // Button height
hWnd, // Parent window
(HMENU)B2, // No menu.
(HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE),
NULL); // Pointer not needed.
SendMessageW(hwndButton2, BM_SETIMAGE, IMAGE_ICON, (LPARAM)IDI_SMALL);
HWND hwndButton3 = CreateWindow(
L"BUTTON", // Predefined class; Unicode assumed
L"THE 3rd KEY", // Button text
WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON | BS_BITMAP, // Styles
240, // x position
10, // y position
100, // Button width
100, // Button height
hWnd, // Parent window
(HMENU)B3, // No menu.
(HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE),
NULL); // Pointer not needed.
HWND hwndButton4 = CreateWindow(
L"BUTTON", // Predefined class; Unicode assumed
L"THE 4th KEY", // Button text
WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_AUTO3STATE, // Styles
360, // x position
10, // y position
300, // Button width
100, // Button height
hWnd, // Parent window
(HMENU)B4, // No menu.
(HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE),
NULL); // Pointer not needed.
SendMessageW(hwndButton4, WM_SETTEXT, NULL, (LPARAM)buttontext);// (LPARAM)IDI_SMALL);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
this same code doesnt respond,but destroywindow worked and quits program
buttons constants are named B1,B2,B3,B4
/
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_COMMAND:
{
int wmId = LOWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case B1:
//handle button here
//SendMessageW(hwndButton, WM_SETTEXT, NULL, &buttontext);
SendMessageW(hwndButton, WM_SETTEXT, NULL, (LPARAM)buttontext);
//DestroyWindow(hWnd);
break;
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
}
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code that uses hdc here...
paint(hdc);
EndPaint(hWnd, &ps);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// Message handler for about box.
So, hwndButton is a local variable of function InitInstance.
That code throws lots of errors, it seems somebody has to add the necessary includes etc.
maybe GetDlgItem (https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-getdlgitem) help, if you don't want to use a global button handles.
Quote from: AW on May 26, 2019, 03:08:43 PM
So, hwndButton is a local variable of function InitInstance.
Thanks
So annoying with c++ overload
The second Hwndbutton 's is globals with same name,but not connected to buttons,not defined
Got it working changing text on B1
Any way to change warning level so it warns about overload?
Thanks timo
Magnus,
I have read through this thread and I still don't know what you are trying to do. A button is just a simple UI component that does not have anything to do with Graphic Device Interface (GDI). It is also a control that you don't have much adjustment with, only text and size. A button press can be accessed as a message from either its handle which is a unique ID number OR its control number.
Now if you want to code a custom button which is not all that hard to do, you create a window using CreateWindowEx() then display whatever interface on it you want. It can be a bitmap or a rectangle where you generally set the text with an API like DrawText(). Let un know what you are try to get as an end result and we may be able to help you.
LATER : Here is the bare minimum for changing a button text while clicking on it.
Quote from: hutch-- on May 26, 2019, 10:28:06 PM
LATER : Here is the bare minimum for changing a button text while clicking on it.
great thanks Steve :thumbsup: :eusa_clap:
now I can work on graphics with GUI version of question and with different answers to click buttons with,which I want to reuse for different answers/questions
a riddle for example
maybe an idea to have a variable called used in switch RIGHTANSWER that is set to the ID of the button with right answer
GDI is for draw some nice background and some person that asks the riddles
testing time
facts from wikipedia
Please test,disabled call to tunnel drawing code
When resizing, it stops with a stack overrun.
Quote from: jj2007 on June 09, 2019, 05:04:01 AM
When resizing, it stops with a stack overrun.
which OS?
dragging window edges?or minimize/maximize?
Magnus,
Crashes on resize here. Win 10 64 Pro.
I myself noted a less serious bug,maybe someone noticed there appear double answers of right answer on buttons,one is coded to be right answer and the other you get wrong answer because of lacking check for double answers
thanks for testing,Hutch,Jochen
I tested myself dragging and it works few pixels before I get exception handler shows up in debug and shows reference to updatewindow and where my GDI drawtext is,too many paint messages is stacked and calls too?
add some exception handling code?
Quote from: daydreamer on June 09, 2019, 08:43:16 PM
which OS?
dragging window edges?or minimize/maximize?
dragging window edges on Win7-64
It looks like you're creating GDI resources (pens, brushes) on every draw, but not cleaning them up again (DeleteObject), only to create them all over again on the next draw, and the next, and the next, and.. oh dear.
It's generally better to create them once at startup, then use them as needed, and delete them on exit.
Another issue is that you're from calling InvalidateRect in response to all WM_COMMAND messages, even ones you're not interested in. Only call InvalidateRect when there is something to be drawn.
For a silly example: note the current question, then click the About menu item -- the question changes.
Quote from: Tedd on June 12, 2019, 10:37:52 PM
It looks like you're creating GDI resources (pens, brushes) on every draw, but not cleaning them up again (DeleteObject), only to create them all over again on the next draw, and the next, and the next, and.. oh dear.
It's generally better to create them once at startup, then use them as needed, and delete them on exit.
Another issue is that you're from calling InvalidateRect in response to all WM_COMMAND messages, even ones you're not interested in. Only call InvalidateRect when there is something to be drawn.
For a silly example: note the current question, then click the About menu item -- the question changes.
I gonna fix that with messages
thanks,maybe better to solve showing score and right wrong different,than to draw it
want to place drawing in a separate thread,so it doesnt make controls laggy
Quote from: daydreamer on June 13, 2019, 01:08:12 AM
thanks,maybe better to solve showing score and right wrong different,than to draw it
want to place drawing in a separate thread,so it doesnt make controls laggy
There shouldn't be any problem with drawing, as long as you do it correctly :tongue:
I don't expect a separate thread will be necessary unless you're planning on doing lots of continuous drawing, i.e. animations.
Quote from: Tedd on June 13, 2019, 05:06:48 AM
Quote from: daydreamer on June 13, 2019, 01:08:12 AM
thanks,maybe better to solve showing score and right wrong different,than to draw it
want to place drawing in a separate thread,so it doesnt make controls laggy
There shouldn't be any problem with drawing, as long as you do it correctly :tongue:
I don't expect a separate thread will be necessary unless you're planning on doing lots of continuous drawing, i.e. animations.
fixed some things
seems like a good plan drawing in separate thread,if possible and make hdc global so I can organize drawing in many separate functions,without need to pass hdc to all those things I want to draw
decided to make some GDI macros that helps shorten down the typing for many gdi calls