Delphi Pages Forums  

Go Back   Delphi Pages Forums > Delphi Forum > VCL

Lost Password?

Reply
 
Thread Tools Display Modes
  #1  
Old 07-11-2016, 11:36 AM
TBill TBill is offline
Junior Member
 
Join Date: Jul 2016
Posts: 3
Default Problem with Minimise Button D7 and Win7

I have a dB utility .exe written in D7, running under Win7. This app can call another Image Editor utility exe using ShellExecute, and when it does, it minimises itself on to the TaskBar, so that the Image Editor can do a screen grab without catching the dB form on screen.

On closing the Image Editor, it sends a WM_SYSCOMMAND SC_RESTORE message to the dB exe, so that the dB form pops back up on screen.

The problem however is that when restored, the dB form Minimise Button ceases to work properly. The button looks like it is pressed by a mouse click, but nothing then happens - no minimising. All the form buttons work OK when this has happened, so its not a crash.

I can get Minimise to work again - I have only to click once on the apps image on the TaskBar and then all seems to go back to normal - the button will minimise the form as it should do.

Anyone got any ideas why this happens? Or suggestions to code around the issue?
Reply With Quote
  #2  
Old 07-11-2016, 11:21 PM
lexd lexd is offline
Senior Member
 
Join Date: Feb 2015
Posts: 268
Default

The minimise request is sent to windows through the API, sometimes Delphi uses in direct calls to the Windows API, you could try Delphi help windows API and look up ShowWindow as one example and see if you get a much more positive result to your problem.
Reply With Quote
  #3  
Old 07-11-2016, 11:27 PM
lexd lexd is offline
Senior Member
 
Join Date: Feb 2015
Posts: 268
Default

This could be a much bigger problem to solve that you may have go to a update is the only cure unless you can make a IDE. Trying change pre written code is impossible because its pre coded in the *.BPL files.
Reply With Quote
  #4  
Old 07-12-2016, 09:46 AM
TBill TBill is offline
Junior Member
 
Join Date: Jul 2016
Posts: 3
Default

Thanks for your suggestion. I have just tried using "ShowWindow" instead of WM_SYSCOMMAND SC_RESTORE. It behaves exactly the same as WM_SYSCOMMAND - frozen minimise action as before.

By the way, I follow both these attempts with "SetForegroundWindow" to make sure the dB utility form has the focus when restored.

The odd thing here is that the dB utility can use its Close Button, and the form's System Menu drops down as normal/expected. I can even Move the window around. Its just the Minimise action that seems frozen. (Note - I have disabled Maximise to prevent the user going full screen - part of the design).

But I have also noticed something else that is odd when the dB form is restored. My dB form has a slightly larger "design" size when it initialises, which I then reduce during Form.Create in order to hide some specific area of the form (user can show/not show this area in a toggle action if they wish). When I first minimise it on to the TaskBar to avoid it cluttering a screen grab from the Image Editor, it is in its "smaller state" (smaller width/height). But when I perform the dB form restore on closing the Image program, then it is shown in its "bigger state" (larger width/height). It has "forgotten" that it was minimised with the smaller width/height.

As I said, I can make it minimise again with a work around. With just a single click on the icon on the TaskBar (even though it is restored on screen), then the Minimise Button starts working again.

I like using the D7 IDE. Its simplicity and speed is delightful. The later IDE's are painfully slower.
Reply With Quote
  #5  
Old 07-12-2016, 10:32 AM
lexd lexd is offline
Senior Member
 
Join Date: Feb 2015
Posts: 268
Default

I think I have shown you another option and yes work arounds may get you their with trial and error. Bugs are like this so good luck as these problems are standard with your version of Delphi that you may reuse on other projects.
You mite make a support file for your self.
Reply With Quote
  #6  
Old 07-13-2016, 10:29 AM
TBill TBill is offline
Junior Member
 
Join Date: Jul 2016
Posts: 3
Default

Very interesting. Further research has shown this issue to be a more widespread problem than I thought – another guy has had exactly the same problem with Minimize Button and running two applications/exe files.

Seems to be related to “interprocess communication”, that is, between two separate programs wanting to interact with each other. I have now actually solved this problem in my own code. Excuse the following “Grandma to suck eggs” but it may be worth explaining detail in case others come across something similar…

It appears to be “bad practice” to try get one .exe program to interfere with the “state” of another .exe. In WindowsSpeak, if one running Process starts to change the state of another running Process, then the internal message queues can get in a mess. I think this is the basic reason why my frozen Minimize Button reacted as normal to my mouse click, but would not actually carry out the Minimize function.

The “correct way” to handle this matter is to let my dB program restore ITSELF from a minimised state on the TaskBar, and to trigger this restoration by sending a “user defined message” (one the operating system is ignorant about) from the Image Editor program. But there is a bit more to add so now some code examples may prove useful.

1. CODE for the Image Editor program (sender of interprocess user defined message):

function AllowSetForegroundWindow(dwProcessId: DWORD): BOOL;
stdcall; external 'user32.dll';

var
ProgramId: DWORD;
dBhWND: hWND;

const
WM_MyMessage = WM_USER+1; // one greater than where user msgs start

… (code) …

dBhWND := FindWindowExtd('WebBase v'); //this parameter string is part of the dB form window caption – identifies it (if running), returns zero if not
if (dBhWND<>0) then
begin
GetWindowThreadProcessId(dBhWND, ProgramId); //find out what the process id is for the dB program
AllowSetForegroundWindow(ProgramId); //function in User32.dll which permits dB to set itself with focus
SendMessage(dBhWND, WM_MyMessage, 0, 0); //send the restore trigger message to dB program
End;


2. CODE for the dB program (receiver of interprocess user defined message):

TForm1 = class(TForm)
...
private
{ Private declarations }
protected
procedure WndProc(var Message: TMessage); override;
public
{ Public declarations }
end;

const
WM_MyMessage = WM_USER+1; // one greater than where user msgs start

… (code) …

procedure TForm1.WndProc(var Message: TMessage);
begin
inherited;
case Message.Msg of //case statement allows possible other user defined msgs
WM_MyMessage:
begin
Form1.Visible := True;
Application.Restore;
Application.BringToFront;
end;
end;
end;
Reply With Quote
  #7  
Old 07-13-2016, 10:29 PM
lexd lexd is offline
Senior Member
 
Join Date: Feb 2015
Posts: 268
Default

This is the type of thing I expected of you to find.
Now you can look to making a patch and calibrating with other users place it on torry pages or something. its a shame embarcadeo do not offer a patch/update.
Glad I can help.
Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT. The time now is 11:40 AM.


Powered by vBulletin® Version 3.8.8
Copyright ©2000 - 2019, vBulletin Solutions, Inc.