GroundFloor
asked on
How to delete a button?
I am trying to learn more about API programming using code i found at:
http://www.swissdelphicenter.ch/en/showcode.php?id=411
I noticed that it did not destroy the window when the program it creates is closed and i seem to have figured that out myself.
However, i put the code in to add a button to the form - but it is not deleted from memory when the program is closed.
Does anyone know how to delete a button created with CreateWindow?
I tried DestroyWindow() but it didn't work and i've looked on the internet but cannot find anything.
http://www.swissdelphicenter.ch/en/showcode.php?id=411
I noticed that it did not destroy the window when the program it creates is closed and i seem to have figured that out myself.
However, i put the code in to add a button to the form - but it is not deleted from memory when the program is closed.
Does anyone know how to delete a button created with CreateWindow?
I tried DestroyWindow() but it didn't work and i've looked on the internet but cannot find anything.
ASKER
Hi Katka
I changed WM_DESTROY: PostQuitMessage(0); to WM_DESTROY: PostQuitMessage(0); DestroyWindow(hWindow)
That destroyed the window on closing.
I added the button with the following code under ShowWindow(hWindow, CmdShow);
Button1 := CreateWindow('Button', 'OK', WS_VISIBLE or WS_CHILD or BS_PUSHLIKE or BS_TEXT,
216, 8, 75, 25, hWindow, 0, hInstance, nil);
I changed WM_DESTROY: PostQuitMessage(0); to WM_DESTROY: PostQuitMessage(0); DestroyWindow(hWindow)
That destroyed the window on closing.
I added the button with the following code under ShowWindow(hWindow, CmdShow);
Button1 := CreateWindow('Button', 'OK', WS_VISIBLE or WS_CHILD or BS_PUSHLIKE or BS_TEXT,
216, 8, 75, 25, hWindow, 0, hInstance, nil);
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thanks for your help Katka
Slick812 - thanks for the demo code. I couldn't get it to work 100% but was able to figure out a few more things from it.
I figured out that each button or other object is a "window" itself and therfore needs to have its "handle" destoyed when exiting the program. A little bit of extra code fixed it.
I increased the points and will split them between you both for your help.
Slick812 - thanks for the demo code. I couldn't get it to work 100% but was able to figure out a few more things from it.
I figured out that each button or other object is a "window" itself and therfore needs to have its "handle" destoyed when exiting the program. A little bit of extra code fixed it.
I increased the points and will split them between you both for your help.
You do not need to destroy any windows that are child windows or other window like the button is a child window of the hWindow, so when the system destroys the hWindow it will automatically destroy the hButton1 window. . . . You do NOT need the -
DestroyWindow(hWindow);
in your code, your message handing is incorrect, you MUST let the system get the WM_DESTROY message to the
DefWindowProc(hWindow, Msg, wParam, lParam);
and not bypass it like your code does
DestroyWindow(hWindow);
in your code, your message handing is incorrect, you MUST let the system get the WM_DESTROY message to the
DefWindowProc(hWindow, Msg, wParam, lParam);
and not bypass it like your code does
program ApiProgram;
uses
Windows, Messages;
{$R *.RES}
var
winClass: TWndClass;
hForm1, hButton1: Integer;
MainMsg: TMSG;
function WindowFunc(hWnd, Msg, wParam, lParam: Integer): Integer; stdcall;
begin
case Msg of
WM_DESTROY: PostQuitMessage(0);
{do not block the WM_DESTROY message, you must let the DefWindowProc be called
with this destroy message for the system to destroy the window and its child windows}
WM_COMMAND: if lParam = hButton1 then PostMessage(hForm1,WM_CLOS E,0,0);
{when a button is clicked a WM_COMMAND message is sent with the lParam set to the
button's Handle}
end;
{there is no special window message handling, so let all messages go to
DefWindowProc just to be safe}
Result := DefWindowProc(hWnd,Msg,wPa ram,lParam );
end;
begin
ZeroMemory(@winClass, SizeOf(winClass));
with winClass do
begin
hInstance := SysInit.hInstance;
hIcon := LoadIcon(hInstance,'MAINIC ON');
lpfnWndProc := @WindowFunc;
hbrBackground := COLOR_BTNFACE+1;
hCursor := LoadCursor(0,IDC_ARROW);
lpszClassName := 'A Class Name';
end;
RegisterClass(winClass);
hForm1 := CreateWindow(winClass.lpsz ClassName,
'Form Caption', // title bar Caption here
WS_OVERLAPPEDWINDOW or WS_VISIBLE, // window style
{WS_OVERLAPPEDWINDOW is the default standard main window with a
Title bar and system menu and sizing border, there is No WS_CHILD here}
100, // horizontal position of window
50, // vertical position of window
356, // window width
220, // window height
0, // handle to parent or owner window
{this is the MAIN window, so it does not have a parent}
0, // handle to menu or child-window identifier
hInstance, // program instance handle
nil // pointer to window-creation data
);
CreateWindow('STATIC','A Title Label',
WS_VISIBLE or WS_CHILD or SS_CENTER,3,10,347,16,hFor m1,0,hInst ance,nil);
hButton1 := CreateWindow('BUTTON', 'Close Me',
WS_VISIBLE or WS_CHILD or BS_PUSHBUTTON,
140,146,64,28,hForm1,0,hIn stance,nil );
SendMessage(hButton1,WM_SE TFONT,GetS tockObject (ANSI_VAR_ FONT),0);
while GetMessage(MainMsg,0,0,0) do
begin
TranslateMessage(MainMsg);
DispatchMessage(MainMsg);
end;
// you do not need to call Halt or anything else here
// program will terminate when it gets to the END. code next
END.
uses
Windows, Messages;
{$R *.RES}
var
winClass: TWndClass;
hForm1, hButton1: Integer;
MainMsg: TMSG;
function WindowFunc(hWnd, Msg, wParam, lParam: Integer): Integer; stdcall;
begin
case Msg of
WM_DESTROY: PostQuitMessage(0);
{do not block the WM_DESTROY message, you must let the DefWindowProc be called
with this destroy message for the system to destroy the window and its child windows}
WM_COMMAND: if lParam = hButton1 then PostMessage(hForm1,WM_CLOS
{when a button is clicked a WM_COMMAND message is sent with the lParam set to the
button's Handle}
end;
{there is no special window message handling, so let all messages go to
DefWindowProc just to be safe}
Result := DefWindowProc(hWnd,Msg,wPa
end;
begin
ZeroMemory(@winClass, SizeOf(winClass));
with winClass do
begin
hInstance := SysInit.hInstance;
hIcon := LoadIcon(hInstance,'MAINIC
lpfnWndProc := @WindowFunc;
hbrBackground := COLOR_BTNFACE+1;
hCursor := LoadCursor(0,IDC_ARROW);
lpszClassName := 'A Class Name';
end;
RegisterClass(winClass);
hForm1 := CreateWindow(winClass.lpsz
'Form Caption', // title bar Caption here
WS_OVERLAPPEDWINDOW or WS_VISIBLE, // window style
{WS_OVERLAPPEDWINDOW is the default standard main window with a
Title bar and system menu and sizing border, there is No WS_CHILD here}
100, // horizontal position of window
50, // vertical position of window
356, // window width
220, // window height
0, // handle to parent or owner window
{this is the MAIN window, so it does not have a parent}
0, // handle to menu or child-window identifier
hInstance, // program instance handle
nil // pointer to window-creation data
);
CreateWindow('STATIC','A Title Label',
WS_VISIBLE or WS_CHILD or SS_CENTER,3,10,347,16,hFor
hButton1 := CreateWindow('BUTTON', 'Close Me',
WS_VISIBLE or WS_CHILD or BS_PUSHBUTTON,
140,146,64,28,hForm1,0,hIn
SendMessage(hButton1,WM_SE
while GetMessage(MainMsg,0,0,0) do
begin
TranslateMessage(MainMsg);
DispatchMessage(MainMsg);
end;
// you do not need to call Halt or anything else here
// program will terminate when it gets to the END. code next
END.
ASKER
Thanks Slick812 - but i tried out yourprogram above when compiled through MemProof to check if everything was deleted as expected.
It pointed out that the button and label was not destroyed and give the message that if CreateWindow or CreateWindowEx is used that the window handle must be destroyed by DestroyWindow or by passing a WM_DESTROY message to the default window procedure.
It also pointed ot that DestroyIcon needed to be used too.
odd?
It pointed out that the button and label was not destroyed and give the message that if CreateWindow or CreateWindowEx is used that the window handle must be destroyed by DestroyWindow or by passing a WM_DESTROY message to the default window procedure.
It also pointed ot that DestroyIcon needed to be used too.
odd?
the MemProof is correct in one way, that you created windows and did not specifically call a function to Destroy them, this is waht it is suppose to do, However! the system will destroy the window in it's WM_DESTROY message sent to the DefWindowProc - - - it seems like you could figure this just from the message name "WM_DESTROY" Also, the system realizes that the child windows of a Destroyed window will be without a parent, so it will automatically perform all nessary system actions needed to destroy ALL of a destroyed window's Child windows. . .
and I do not understand the reference to -
DestroyIcon
I use the LoadIcon( ) function which does NOT require a DestroyIcon. . .
you really should read the Win32 Help for all of the API Functions, Messages and Methods you use in your code, the Help has some useful information about what you need to do or use many times. . .
I have already given you a web address for a web site that you should go to and read up on using API to make windowed projects -
http://www.angelfire.com/hi5/delphizeus/index.html
and the page that explaines window creation and handles and messages is at -
http://www.angelfire.com/hi5/delphizeus/first1.html
it is worth your time to read that page if you are going to do anymore API programming
and I do not understand the reference to -
DestroyIcon
I use the LoadIcon( ) function which does NOT require a DestroyIcon. . .
you really should read the Win32 Help for all of the API Functions, Messages and Methods you use in your code, the Help has some useful information about what you need to do or use many times. . .
I have already given you a web address for a web site that you should go to and read up on using API to make windowed projects -
http://www.angelfire.com/hi5/delphizeus/index.html
and the page that explaines window creation and handles and messages is at -
http://www.angelfire.com/hi5/delphizeus/first1.html
it is worth your time to read that page if you are going to do anymore API programming
if you want current information about the API methods, you might go to the MSDN developers library at -
http://msdn.microsoft.com/library/default.asp
and do word searches for specific functions, messages, things (like - windows, buttons, messages, edits).
you may want to read all of the pages that are availiable at the MSDN Library for the subject of "Windows", , starts at page -
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/windowing/windows.asp
http://msdn.microsoft.com/library/default.asp
and do word searches for specific functions, messages, things (like - windows, buttons, messages, edits).
you may want to read all of the pages that are availiable at the MSDN Library for the subject of "Windows", , starts at page -
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/windowing/windows.asp
The problem is probably in specifying a
parental component and your window is
not aware of containing it (the button).
regards,
Kate