Icon View Thread

The following is the text of the current message along with any replies.
Messages 11 to 14 of 14 total
Thread Switching database before login
Fri, Jan 20 2017 7:28 AMPermanent Link

Roy Lambert

NLH Associates

Team Elevate Team Elevate

Peter

>Just curious, is that activated by a timer, a EDBDBDataSet.AfterPost or does it respond to some form of database Notification?

None of the above Smiley

If you look at te function header you'll see (var Message: TMessage); which indicates that it responds to a Windows message. In this case its generated by a menu button click which calls

procedure TMainForm.SendRefreshMessage(Tag: integer);
begin
if IsCreated[tagProject] and ((Tag < 0) or (Tag = tagProject)) then
 PostMessage(frmHndl[tagProject], DoRefreshRequest, 0, 0);
if IsCreated[tagCompanies] and ((Tag < 0) or (Tag = tagCompanies)) then
 PostMessage(frmHndl[tagCompanies], DoRefreshRequest, 0, 0);
if IsCreated[tagContacts] and ((Tag < 0) or (Tag = tagContacts)) then
 PostMessage(frmHndl[tagContacts], DoRefreshRequest, 0, 0);
if IsCreated[tagIntroductions] and ((Tag < 0) or (Tag = tagIntroductions)) then
 PostMessage(frmHndl[tagIntroductions], DoRefreshRequest, 0, 0);
if IsCreated[tagOrderBook] and ((Tag < 0) or (Tag = tagOrderBook)) then
 PostMessage(frmHndl[tagOrderBook], DoRefreshRequest, 0, 0);
if IsCreated[tagEMails] and ((Tag < 0) or (Tag = tagEMails)) then
 PostMessage(frmHndl[tagEMails], DoRefreshRequest, 0, 0);
if IsCreated[tagAlarms] and ((Tag < 0) or (Tag = tagAlarms)) then
 PostMessage(frmHndl[tagAlarms], DoRefreshRequest, 0, 0);
if IsCreated[tagLTC] and ((Tag < 0) or (Tag = tagLTC)) then
 PostMessage(frmHndl[tagLTC], DoRefreshRequest, 0, 0);
if IsCreated[tagCallbacks] and ((Tag < 0) or (Tag = tagCallbacks)) then
 PostMessage(frmHndl[tagCallbacks], DoRefreshRequest, 0, 0);
end;

In this application I have multiple forms hosted on a pagecontrol (much better than MDI in my opinion). Whlst I have a datamodule with the engine, session and database I decided to have separate table instances on each form so its possible for them to get out of synch. Click on the menu button and it send a refresh message to each of the principal forms that is open.. Each form has a function that responds to the message in its own way.

You've seen the one for contacts here's the one for the email form

procedure TProjectForm.ExecuteRefreshRequest(var Message: TMessage);
begin
case Self.Tag of
 tagProject: if iProject <> 0 then GrabProject(iProject, iProjectName);
 tagCallbacks: GrabNonProject(tagMode, 'Contact');
 tagAlarms: PostMessage(Self.Handle, ConfigureProjectPage, 0, 0);
else begin
  if tagMode = tmHeadhunt then
   GrabNonProject(tagMode, Project.IndexName)
  else
   GrabProject(iProject, iProjectName);
 end;
end;
SyncTables(Self);
end;


As you see - same name (just because its easier to remember), different actions.

Roy Lambert
Fri, Jan 20 2017 8:16 PMPermanent Link

Peter

Roy Lambert wrote:

<<None of the above Smiley>

Another great idea. I hadn't considered using Messages, but I will now.

Thanks Roy

Peter
Sat, Jan 21 2017 2:19 AMPermanent Link

Roy Lambert

NLH Associates

Team Elevate Team Elevate

Peter


If you start slinging messages around beware! It is possible for a window's handle to be recreated (including a form's). Its not a massively common event but if you look through the VCL code you'll see lots of RecreateWnd calls.

What I've do is declare a common variable (ie declared in a shared and used everywhere unit) and then in the main forms OnCreate

MainHWND := Classes.AllocateHWND(MainHWNDHandler);

This

 procedure MainHWNDHandler(var msg: TMessage);

which is my own message handler goes in the main form's type declaration

procedure TMainForm.MainHWNDHandler(var msg: TMessage);
var
pca: TPageCloseAction;
begin
if MonitorIsOn and (not RunningIsolated) then begin
 case msg.Msg of
  CloseMainProject: begin
    FormControllerClosePage(Self, tagProject, pca);
    FormController.ActivePageIndex := 0;
   end;
{$IFNDEF NOALARMCHECKS}
  AlarmPopupMessage: DisplayPopupAlarm(msg);
{$ENDIF}
  ProgressReport: FilterResult(msg);
  jmpRequired: ProcessJumpInstruction(msg);
  StatusMessage: ChangeStatusMessage(msg);
  PinToJump: AddToJumpButton(msg);
....
....
  PingingDone: if not AppClosing then ToolsMnu.MnuImage[mnuPingTest] := -1;
  //roy alter to refreshing email display   EMailsSkipped: EmailsHaveBeenSkipped(msg);
 else
  msg.Result := DefWindowProc(Self.Handle, msg.Msg, msg.wParam, msg.lParam);
 end;
end else msg.Result := DefWindowProc(Self.Handle, msg.Msg, msg.wParam, msg.lParam);
end;


Finally, in the FormClose event I have a call to    RemoveMainHWND;

procedure TMainForm.RemoveMainHWND;
var
Instance: Pointer;
begin
Instance := Pointer(GetWindowLong(MainHWND, GWL_WNDPROC));
if Instance <> @DefWindowProc then
 // make sure we restore the old, original windows procedure before leaving
 SetWindowLong(MainHWND, GWL_WNDPROC, Longint(@DefWindowProc));
FreeObjectInstance(Instance);
DestroyWindow(MainHWND);
end;


Roy Lambert
Sun, Jan 22 2017 8:39 AMPermanent Link

Adam Brett

Orixa Systems

Peter

You have a number of options. One which I think should work, and would be fairly easy given the way your app is written, would be to iterate the DM changing property values based on Class-Type.

In the code below, I am assuming your DM is called "Datamodule1" and the Database name is passed around as: MyLocalDatabaseNameVariable. Obviously you'll have to reset all these to the correct names in your app.

(Please note I haven't tested this code at all, but I hope it will provide you with a useful pointer)

<Add this code to some procedure in your application, such as "BeforeConnect" of Database or Session>
var
 i : integer;
begin
 for i:= 0 to DataModule1.ComponentsCount - 1 do
   begin
      if Datamodule1.Components[i] is TEDBSession then
         (Datamodule1.Components[i] as TEDBSession).DatabaseName:= MyLocalDatabaseNameVariable
//          ... add lines to set any other properties for the EDBSession here ...
      if Datamodule1.Components[i] is TEDBDatabase then
         (Datamodule1.Components[i] as TEDBDatabase).DatabaseName:= MyLocalDatabaseNameVariable


   end;
end;

Hope this is useful.
« Previous PagePage 2 of 2
Jump to Page:  1 2
Image