-2

I need to select the component on currently focused/active form, but can't figure the way of doing this completely. So, I have a delphi unit with all common procedures on it, so I call them from other forms. Now, the thing is, that with one of the procedures I call the component show action, but, since the component is placed on each form (couldn't find a way of placing one component, which can be used by all forms, but I think this somehow can't be done. Am I wrong? ), I need to call a show event for the component on currently active form, otherwise the specified form, from which I call the component, gets active and focused.

So far I've tried by getting current form name, via Screen.ActiveForm and Screen.ActiveForm.Name, but none of this works, since the compiler doesn't compile because component parent is not defined (getting error " 'TForm' does not contain a member named 'KeyBoard1' "...)

Here's the procedure code:

  procedure KeyDownEvents(var Key: Word; Shift: TShiftState);
    begin
    CurrentForm:=Screen.ActiveForm.Name;
    if Key = VK_F9 then CurrentForm.KeyBoard1.Show;
    end;

Using global variable

    var CurrentForm: TForm;

Where and what am I missing, since I've tried like 10 different combinations...?

Thanks,

Marc.

Ps: as asked above, is there a way of placing or calling component, to be active on any form, or should it be placed in each form, so no focus is changed...? I know in MDI I could use a component in main form (as far as I know...), but I'm working in SDI, because of multiple monitors needed...


Complete code for David:

unit CommonProcedures;

interface

uses Classes, Dialogs, StdCtrls, Math, Winapi.Windows, Winapi.Messages,
Vcl.Controls, Vcl.Forms, AdvTouchKeyboard;

procedure KeyDownEvents(var Key: Word; Shift: TShiftState);

var
CurrentForm: TComponentName;
KeyBoard1Visible: Boolean;

implementation


uses Startup, Main, Controller, Settings, Patch, Output, StageVisual, FixturesEditor,
FixturesEditorGlobal;

procedure KeyDownEvents(var Key: Word; Shift: TShiftState);
 begin
  CurrentForm:=Screen.ActiveForm.Name;
   if ((ssAlt in Shift) and (Key = VK_F4)) then Key:=0;
   if Key = VK_F1 then Main1.Show;
   if Key = VK_F2 then Controller1.Show;
   if Key = VK_F3 then Settings1.Show;
   if Key = VK_F4 then Patch1.Show;
   if Key = VK_F5 then Output1.Show;
   if Key = VK_F6 then StageVisual1.Show;
   if Key = VK_F7 then FixturesEditor1.Show;
   if Key = VK_F8 then FixturesEditor2.Show;
   if Key = VK_F9 then
     begin
       if KeyBoard1Visible=False
       then
        begin
          KeyBoard1Visible:=True;
          CurrentForm.KeyBoard1.Show;
        end
       else
        begin
         KeyBoard1Visible:=False;
         CurrentForm.KeyBoard1.Hide;
       end;
     end;
  end;

end.

There you can see, that I only left out all other key events, since they're completely unimportant, but I did as well left out process of checking whether the keyboard is shown or hidden, so the VK_F9 behaves as toggle key.

That is so far the only procedure in this unit, as I only started to create the program a few days ago, so it's still in first base, so said... And yes, as you can see and guess, it's sort of light-show controller program, the project for my senior year.

Ps: don't see the reason to downvote the question when I edited it to be even clearer...

That Marc
  • 1,134
  • 3
  • 19
  • 42
  • I'm disappointed that you posted fake code here. Please don't ever do that. Always post real code. I've also got no idea what the PS means. Please try to ask one question at a time. – David Heffernan Mar 04 '13 at 15:07
  • That IS the real, not fake code, but it's true, it's only part of it. I indeed use Keyboard1 instead of AdvPopupTouchKeyBoard1, because it's long and makes no sense of keeping it that way for me... Will post as answer below the whole procedure code, so you'll see what and why I left it out... No hard feelings, but I'm not trying to hide anything... – That Marc Mar 04 '13 at 15:23
  • The PS meant, if there is a way of having that Keyboard somewhere, to be called on any form, while the form remains active, or do I need to place the keyboard component on each form separately; I asked this as for bytheway because I thought it might be a part or one version of answer/simpler way of doing this; – That Marc Mar 04 '13 at 15:25
  • 1
    It's not the real code. For example, that's not what an event handler looks like. It looks like `procedure TMyFormClass.EventName`. And what's more, `CurrentForm := Screen.ActiveForm.Name` is a type mismatch. It's important to post the exact code that you are using. Even if that means adapting it to be suitable for a question. – David Heffernan Mar 04 '13 at 15:37
  • I also question why you use a global variable. They are generally to be shunned. Is there are reason for that? – David Heffernan Mar 04 '13 at 15:37
  • Can't post the real code for next 6 hours, so I'll attach it BELOW my primary question. Take a look at it, and you'll understand. The procedure is NOT event handler, it's internal procedure, as it is in the Unit, not form! That's the procedure I'm calling from other units, so I don't copy entire procedure in all of the forms. The type is mismatch, yes, that's correct, and I corrected it later, but didn't post it here: the CurrentForm: TComponentName is the variable I use right now, I forgot to change that here - I posted question while still trying to figure things out. – That Marc Mar 04 '13 at 15:48
  • I don't see why you need to wait 6 hours. You'd need to do that if you were answering your own question. I don't think you need to do that. – David Heffernan Mar 04 '13 at 15:50
  • So yes, unlike for the type mismatch, which I didn't see at the moment, but found later in errors, yes, I posted the real code, just shorten! Using global variable has no reason at all, it's just that in this case I'm able to call it wherever needed (in other forms), so I kinda get used to place all this "bigger" (not procedure dependend variables) as a global, above implementation... no reason, just the pick of choice... – That Marc Mar 04 '13 at 15:54
  • Yes, that's what I wanted to do : answer my own question, so I don't correct my original question. Sorry. – That Marc Mar 04 '13 at 15:56
  • 1
    You can only answer if you have an answer. Updating the original question is fine and in fact to be encouraged. – David Heffernan Mar 04 '13 at 16:13
  • I deleted my answer since your comments to it indicated that there are important details missing from the question. – David Heffernan Mar 04 '13 at 17:31
  • 1
    I'm sorry for inconveniences.. – That Marc Mar 04 '13 at 19:40

1 Answers1

1

It can be done. It does kind of depend on exactly how the components are setup on the forms, as in whether they are the same name and type. For example, here are two methods:

procedure TfrmSiteMapMain.dummy();
Var
  comp : TComponent;
begin
  // Find component by Name
  comp := screen.ActiveForm.FindComponent('btnMyButtonName');
  if comp <> nil then TButton(comp).Click;
end;

or

procedure TfrmSiteMapMain.dummy();
Var
  comp : TControl;
  i : integer;
  frm : TForm;
begin
  frm := screen.ActiveForm;
  for i := 0 to frm.ControlCount -1 do begin
    comp := frm.Controls[i];
    // If you had multiple components, here's where you could check its name, tag, etc
    if comp.ClassNameIs('TButton') then begin
      Break;
    end;
  end;
  if comp <> nil then TButton(comp).Click;
end;

Be aware that the forms have a Controls collection and a Component collection.

Edited to add: Considering the code you posted above, you could to this: (I don't have the Keyboard component, but I'm guessing it's a TKeyboard)

if Key = VK_F9 then ToggleKeyboard;

procedure ToggleKeyboard;
Var
  frm : TForm;
  comp : TComponent;
begin
  frm := Screen.ActiveForm;
  if frm <> nil then begin
    comp := frm.FindComponent('Keyboard1');
    if comp <> nil then begin
      TKeyboard(comp).Visible := not TKeyboard(comp).Visible; // toggle it
    end;
  end;
end;
MikeD
  • 627
  • 6
  • 10
  • Interesting example. Will try out this too. Thanks – That Marc Mar 04 '13 at 16:07
  • Edited due to commenting not supporting code, see edited answer above. – MikeD Mar 04 '13 at 16:27
  • The last one works like PERFECTLY!, except for the toggle action, since the Keyboard component does not have the Visible property to set boolean, but Show and Hide commands. For that I gave the "begin end" part in the last if statement from my original code; I posted as another answer the whole code so it's in one piece as it should be. However, I accepted your answer. Thank you!!! – That Marc Mar 04 '13 at 19:54
  • Will post in 3 hours, when The site will allow. – That Marc Mar 04 '13 at 19:56
  • 1
    No, please don't post your code. It won't have value for future visitors. Mike's answer has solved your problem. That's enough. It's over. We aren't interested in the gory details of your specific code. We don't need to know the precise syntax that you need to toggle. You need to know that, and you've worked it out. – David Heffernan Mar 04 '13 at 20:58
  • 3
    Ok, ok... Gosh, have I killed someone or something...? – That Marc Mar 04 '13 at 21:03
  • 1
    Marc, you seem like you would benefit from reading a big Delphi book, I suggest you go get one. Beginners are welcome here, but it would be good if you had read and studied a bit more before you tried to build something. It's making my head hurt just wondering how someone is going to help you when the basics of variables, classes, units, forms and data modules are still beyond your grasp. – Warren P Mar 05 '13 at 02:56