Ok, I set up a procedure to disable the controls I want. But there's a weird problem, one of the buttons refuse to be disabled.
EnableCtrls proc dwEnabledOrDisable:DWORD
invoke EnableWindow,hUnpackButton,dwEnabledOrDisable ; <---------------------- This one refuses to be disabled.
invoke EnableWindow,hPackButton,dwEnabledOrDisable
invoke EnableWindow,hBackupCheckbox,dwEnabledOrDisable
invoke EnableWindow,hBrowseButton,dwEnabledOrDisable
invoke EnableWindow,hProfileComboBox,dwEnabledOrDisable
invoke UpdateWindow,hWindow
ret
EnableCtrls endp
Anyone have ANY idea why this might happen?
Try to update it with UpdateWindow.
hth.
Hi!
I do an UpdateWindow at the end of that proc, on the main window. Should I do one on the specific button perhaps? Cheers!
Quote from: vogelsang on January 16, 2015, 10:08:04 PM
Try to update it with UpdateWindow.
hth.
I see that you updating hWindow - main window as you say. Try to update hUnpackButton and see what will happen.
And what exactly means "refusing". According to MSDN EnableWindow returns:
Quote
Return value
Type: BOOL
If the window was previously disabled, the return value is nonzero.
If the window was not previously disabled, the return value is zero.
I guess it doesn't changed its state to other?
Maybe this helps:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms646291%28v=vs.85%29.aspx (http://msdn.microsoft.com/en-us/library/windows/desktop/ms646291%28v=vs.85%29.aspx)
Get a handle for each control, then use EnableWindow().
perhaps the control has keyboard focus
if it's stubborn, try removing focus and also try de-activating it
http://blogs.msdn.com/b/oldnewthing/archive/2004/08/04/208005.aspx (http://blogs.msdn.com/b/oldnewthing/archive/2004/08/04/208005.aspx)
http://msdn.microsoft.com/en-us/library/windows/desktop/ms646311%28v=vs.85%29.aspx (http://msdn.microsoft.com/en-us/library/windows/desktop/ms646311%28v=vs.85%29.aspx)
http://msdn.microsoft.com/en-us/library/windows/desktop/ms646312%28v=vs.85%29.aspx (http://msdn.microsoft.com/en-us/library/windows/desktop/ms646312%28v=vs.85%29.aspx)
if all else fails, try SetWindowPos with appropriate flags
http://msdn.microsoft.com/en-us/library/windows/desktop/ms633545%28v=vs.85%29.aspx (http://msdn.microsoft.com/en-us/library/windows/desktop/ms633545%28v=vs.85%29.aspx)
you can use SWP_NOMOVE and SWP_NOSIZE - no need to set the position arguments
flags are OR'ed together, for example...
SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE
Quote from: hutch-- on January 16, 2015, 11:13:46 PM
Get a handle for each control, then use EnableWindow().
Hi!
That's what I'm doing, but this one button refuse to gt disabled when I do invoke EnableWindow,hButton,FALSE. :icon_confused:
I checked the return value, and it is 0, ie. it was not disabled before.
Will see if dedndave:s input might help.
Cheers!
Might be handy to see the code where you assign the handle hUnpackButton - just to make sure there arent any typos or maybe a wrong const value used for IDC_UNPACKBUTTON or whatever its named in your resources.
If after two nights of bugchasing you still haven't found it, here is a top secret information for you:
QuoteTo get extended error information, call GetLastError.
Hello
I use this in my code to enable or disable many Controls
invoke EnableControl,hWnd,1001,TRUE
or
invoke EnableControl,hWnd,1001,FALSE
EnableControl proc uses ebx hWnd:HWND,_ID:DWORD,_bool:BYTE
invoke GetDlgItem,hWnd,_ID
mov ebx,eax
invoke EnableWindow,ebx,_bool
ret
EnableControl endp
Greets,
Hi!
I don't user resources, I create them using CreateWindowsEx. Looks like this:
invoke CreateWindowEx,0,ADDR ButtonClass,ADDR szPackButton,WS_CHILD or WS_VISIBLE or WS_TABSTOP or WS_DISABLED,350,169,75,24,hWindow,NULL,hInst,NULL
mov hPackButton,eax
Quote from: fearless on January 17, 2015, 02:19:46 AM
Might be handy to see the code where you assign the handle hUnpackButton - just to make sure there arent any typos or maybe a wrong const value used for IDC_UNPACKBUTTON or whatever its named in your resources.
Do you get a valid window handle from CreateWindowEx?
Hi!
Yes, I get a valid windows handle. But it looks like the EnableCtrls procedure is called twice. So I think there's something wrong in my main WindowProc.
Right now I do:
.elseif uMsg == WM_COMMAND
.if eax == hPackButton
...
But I seem to recall dedndave telling me once that I should use wParam and check the hi and lo word. So looking in to that.
Quote from: sinsi on January 19, 2015, 07:50:43 PM
Do you get a valid window handle from CreateWindowEx?
Ok, so now I got this:
.elseif uMsg == WM_COMMAND
mov edx,[wParam]
movzx eax,dx
shr edx,16
.if edx == BN_CLICKED
So now it should only execute on BN_CLICKED? Do I just put lParam in to eax then and get the handle? What's best practice in this case?
I use the wNotifyCode mainly for comboboxes and other controls sometimes. You can still specify a control id when creating it using CreateWindowEx - its the third last parameter: hMenu - which can be a control id, like iDC_BtnPack or IDC_BtnUnpack or whatever.
.CONST
IDC_BtnPack EQU 1001
IDC_BtnUnpack EQU 1002
.DATA
ButtonClass db 'button',0
szPackButton db 'Pack',0
szUnpackButton db 'Unpack',0
.DATA?
hUnpackButton dd ?
hPackButton dd ?
.CODE
WndProc proc hWin:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
LOCAL wNotifyCode:DWORD
mov eax, uMsg
.IF eax==WM_INITDIALOG
; do init stuff here, including possibly creating our btn controls here (or somewhere else perhaps, assuming we have hInstance already stored)
invoke CreateWindowEx,0,ADDR ButtonClass,ADDR szPackButton,WS_CHILD or WS_VISIBLE or WS_TABSTOP or WS_DISABLED,350,169,75,24,hWin,IDC_BtnPack,hInstance,NULL
mov hPackButton,eax
invoke CreateWindowEx,0,ADDR ButtonClass,ADDR szUnpackButton,WS_CHILD or WS_VISIBLE or WS_TABSTOP or WS_DISABLED,350,169,75,24,hWin,IDC_BtnUnpack,hInstance,NULL
mov hUnpackButton,eax
.ELSEIF eax == WM_COMMAND
mov eax, wParam
shr eax, 16
mov wNotifyCode, eax
mov eax,wParam
and eax,0FFFFh
.IF eax==IDC_BtnUnpack
; do something here
.ELSEIF eax==IDC_BtnPack
; do something else here
.ELSEIF eax==IDC_SomeOtherControl
; maybe we check to enable disable controls here, like if user has succesfully opened a file - allow unpack button?
.ENDIF
; other code here onwards
Changed my code to use constants for the win-controls. Still no go though. :( The Unpack-button still refuse to be disabled. If I put in a MessageBox call I can see ALL the buttons greyed out. So feels like an update problem? But I do a call to invoke UpdateWindow,hWindow, so should work. :dazzled:
Quote from: fearless on January 19, 2015, 11:39:56 PM
I use the wNotifyCode mainly for comboboxes and other controls sometimes. You can still specify a control id when creating it using CreateWindowEx - its the third last parameter: hMenu - which can be a control id, like iDC_BtnPack or IDC_BtnUnpack or whatever.
.CONST
IDC_BtnPack EQU 1001
IDC_BtnUnpack EQU 1002
.DATA
ButtonClass db 'button',0
szPackButton db 'Pack',0
szUnpackButton db 'Unpack',0
.DATA?
hUnpackButton dd ?
hPackButton dd ?
.CODE
WndProc proc hWin:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
LOCAL wNotifyCode:DWORD
mov eax, uMsg
.IF eax==WM_INITDIALOG
; do init stuff here, including possibly creating our btn controls here (or somewhere else perhaps, assuming we have hInstance already stored)
invoke CreateWindowEx,0,ADDR ButtonClass,ADDR szPackButton,WS_CHILD or WS_VISIBLE or WS_TABSTOP or WS_DISABLED,350,169,75,24,hWin,IDC_BtnPack,hInstance,NULL
mov hPackButton,eax
invoke CreateWindowEx,0,ADDR ButtonClass,ADDR szUnpackButton,WS_CHILD or WS_VISIBLE or WS_TABSTOP or WS_DISABLED,350,169,75,24,hWin,IDC_BtnUnpack,hInstance,NULL
mov hUnpackButton,eax
.ELSEIF eax == WM_COMMAND
mov eax, wParam
shr eax, 16
mov wNotifyCode, eax
mov eax,wParam
and eax,0FFFFh
.IF eax==IDC_BtnUnpack
; do something here
.ELSEIF eax==IDC_BtnPack
; do something else here
.ELSEIF eax==IDC_SomeOtherControl
; maybe we check to enable disable controls here, like if user has succesfully opened a file - allow unpack button?
.ENDIF
; other code here onwards
as it happens, BN_CLICKED is 0 :biggrin:
so - no need to check it because if the entire dword is the control ID, then it is a BN_CLICKED notification
however, you are checking against the handle value
use the control ID's, instead
http://msdn.microsoft.com/en-us/library/windows/desktop/ms647591%28v=vs.85%29.aspx (http://msdn.microsoft.com/en-us/library/windows/desktop/ms647591%28v=vs.85%29.aspx)
notice that, for menu items, the wParam high word is also 0
for controls, the high word is the notification code (BN_CLICKED = 0)
just make sure to use different ID values for controls and menu items
IDC_BUTTON1 EQU 101
IDC_BUTTON2 EQU 102
IDM_MENUITEM1 EQU 103
IDM_MENUITEM2 EQU 104
mov eax,uMsg
.if eax==WM_COMMAND
mov edx,wParam
.if edx==IDC_BUTTON1
.elseif edx==IDC_BUTTON2
.elseif edx==IDC_MENUITEM1
.elseif edx==IDC_MENUITEM2
Quote from: Landsfiskalen on January 20, 2015, 12:18:35 AMBut I do a call to invoke UpdateWindow,hWindow, so should work. :dazzled:
UpdateWindow is needed only on extremely rare occasions. You would have had a solution to your problem a long time ago if
a) you would do error checking, e.g. with the Masm32 macro LastError$()
b) you would post your complete code.
Guessing around like you currently do is just wasting everybody's time, including your own.
Quote from: Landsfiskalen on January 19, 2015, 07:27:52 PM
Hi!
I don't user resources, I create them using CreateWindowsEx. Looks like this:
invoke CreateWindowEx,0,ADDR ButtonClass,ADDR szPackButton,WS_CHILD or WS_VISIBLE or WS_TABSTOP or WS_DISABLED,350,169,75,24,hWindow,NULL,hInst,NULL
mov hPackButton,eax
when you use CreateWindowEx, and the class pointer points to a string that defines a system-defined control,
the hMenu argument of CreateWindowEx should be the control ID
(the system class string for buttons is "button",0)
http://msdn.microsoft.com/en-us/library/windows/desktop/ms632680%28v=vs.85%29.aspx (http://msdn.microsoft.com/en-us/library/windows/desktop/ms632680%28v=vs.85%29.aspx)
IDC_BUTTON1 EQU 101
invoke CreateWindowEx,0,ADDR ButtonClass,ADDR szPackButton,
WS_CHILD or WS_VISIBLE or WS_TABSTOP or WS_DISABLED,
350,169,75,24,hWindow,IDC_BUTTON1,hInst,NULL
now, you can use WM_COMMAND wParam to check the control ID number :t
Hi!
I've made those changes, so I have equates for all controls. Still no go. :( Here's the code if anyone have any ideas.
Quote from: dedndave on January 20, 2015, 02:38:03 AM
Quote from: Landsfiskalen on January 19, 2015, 07:27:52 PM
Hi!
I don't user resources, I create them using CreateWindowsEx. Looks like this:
invoke CreateWindowEx,0,ADDR ButtonClass,ADDR szPackButton,WS_CHILD or WS_VISIBLE or WS_TABSTOP or WS_DISABLED,350,169,75,24,hWindow,NULL,hInst,NULL
mov hPackButton,eax
when you use CreateWindowEx, and the class pointer points to a string that defines a system control,
the hMenu argument of CreateWindowEx should be the control ID
(the system class string for buttons is "button",0)
http://msdn.microsoft.com/en-us/library/windows/desktop/ms632680%28v=vs.85%29.aspx (http://msdn.microsoft.com/en-us/library/windows/desktop/ms632680%28v=vs.85%29.aspx)
invoke CreateWindowEx,0,ADDR ButtonClass,ADDR szPackButton,
WS_CHILD or WS_VISIBLE or WS_TABSTOP or WS_DISABLED,
350,169,75,24,hWindow,IDC_BUTTON1,hInst,NULL
now, you can use WM_COMMAND wParam to check the control ID number :t
first - no need to open a ".const" section for EQUates
won't hurt anything, but EQUates are simply assemble-time constants
they don't create any run-time data
your code looks better,
however, ALL system-defined controls should have an ID
this includes edit controls and static controls (used as labels in your program)
i want to clarify....
in fact, any child window (which includes controls) should probably have an ID assigned
i have seen people use 0 as an ID number, but i wouldn't do that :P
so, the hMenu argument for CreateWindowEx....
for top-level windows, either 0 or a menu handle
for child-level windows, a unique control ID number from 1 to 65535
there is actually no rule that says they have to be unique, but it will make more sense if they are :t
if you run out of numbers, you have too many controls - lol
Quote from: Landsfiskalen on January 20, 2015, 02:42:35 AMStill no go. :( Here's the code if anyone have any ideas.
The unpack button gets disabled or enabled, at least on my Win7-64, and I see no reason why it shouldn't. Try this:
.if wNotifyCode == BN_CLICKED
.if eax == IDC_BUTTON_BROWSE
if 1
.data?
toggle dd ?
.code
not toggle
invoke EnableWindow,hUnpackButton, toggle
invoke EnableWindow,hPackButton, toggle
else
mov ofn.lStructSize,SIZEOF ofn
push hWnd
pop ofn.hwndOwner
push hInstance
pop ofn.hInstance
mov ofn.lpstrFilter, OFFSET szFilterString
mov ofn.lpstrFile, OFFSET buffer
mov ofn.nMaxFile,MAXSIZE
mov ofn.Flags, OFN_FILEMUSTEXIST or \
OFN_PATHMUSTEXIST or OFN_LONGNAMES or\
OFN_EXPLORER or OFN_HIDEREADONLY
mov ofn.lpstrTitle, OFFSET szOpenFileTitle
invoke GetOpenFileName, ADDR ofn
.if eax==TRUE
invoke SendMessage,hInputEdit,WM_SETTEXT,0,ADDR buffer
invoke EnableWindow,hPackButton,TRUE
invoke EnableWindow,hUnpackButton,TRUE
.endif
endif
ok - had a little time to spend on this
cleaned up the code a bit
i also create all the controls in a PROC, and call it from WM_CREATE (and added ID's for all controls)
i think a big problem was the use of tabs - and improper indentation in WndProc
i am a bit OCD about tabs :lol:
getting the indents to align helped me find an .endif that was out of place
; .endif this one was a mistake, removed <------------------
.elseif eax==IDC_COMBOBOX_PROFILE
;IDC_COMBOBOX_PROFILE code
.endif ;end of IDC tests
.endif ;end of BN_CLICKED - added this one <------------------
i also modified the structure of WndProc so each WM_ message may return seperate values in EAX
there are 2 places where...
.if eax==0
.break
.endif
should be replaced with...
.break .if (!eax)
i'll let you decide on that one
i also try to avoid using locals in WndProc and WinMain (especially WndProc)
that's another discussion :P
Wow! Thanks alot! Will have a proper look at this during the weekend. Thanks again! :)
Quote from: dedndave on January 21, 2015, 02:33:53 AM
ok - had a little time to spend on this
cleaned up the code a bit
i also create all the controls in a PROC, and call it from WM_CREATE (and added ID's for all controls)
i think a big problem was the use of tabs - and improper indentation in WndProc
i am a bit OCD about tabs :lol:
getting the indents to align helped me find an .endif that was out of place
; .endif this one was a mistake, removed <------------------
.elseif eax==IDC_COMBOBOX_PROFILE
;IDC_COMBOBOX_PROFILE code
.endif ;end of IDC tests
.endif ;end of BN_CLICKED - added this one <------------------
i also modified the structure of WndProc so each WM_ message may return seperate values in EAX
there are 2 places where...
.if eax==0
.break
.endif
should be replaced with...
.break .if (!eax)
i'll let you decide on that one
i also try to avoid using locals in WndProc and WinMain (especially WndProc)
that's another discussion :P