|
code
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Help using SendMessage() functionHello,
Can anyone tell me how I could get a browser app to display a specific page (by name or by indexID), using the API SendMessage function? Thanks in advance.. Garry GS wrote:
> Can anyone tell me how I could get a browser app to display a specific page Why do you want to use SendMessage, and what the heck is an IndexID wrt a webpage?> (by name or by indexID), using the API SendMessage function? At any rate, to fire off a web page in the default browser, it's as simple as: Private Sub HyperJump(ByVal URL As String) Call ShellExecute(0&, vbNullString, URL, vbNullString, _ vbNullString, vbNormalFocus) End Sub More info: http://vb.mvps.org/samples/HyperJmp Hi Karl,
Thanks for your reply. I need to use SendMessage because it's not a standard web browser, it's a browser app that displays html pages (ie: ebook). It doesn't respond to the standard browser (like IE) keystrokes and so SendKey is not an option. An IndexID is similar to the context ID for a CHM topic page. This wouldn't be used so much as the page name (ie: "somepage.htm") but it can be if desired. Basically, it's a stand-alone EXE that I have managed to get to behave like a CHM in that it is controlled much in the same way as far as opening, closing, and taking focus when minimized or not the top window. This is done entirely using SendMessage. All I need to finish it off is to be able to specify which page (topic) to display. I know this is possible because the author of the software that creates the EXEs uses SendMessage to display context sensitive help in one of these apps. The problem is he uses Delphi, which is jibberish to me, and didn't provide all the source code that performs this. He has a SDK API that's not registerable (regsrver32 doesn't like it) and so I can't use it with VBA projects. I believe it uses pointers to pass the lParam arg, which I suspect is similar to using AddressOf in VB but not sure because I'm relatively new to programming. Any help here would be greatly appreciated. Kind regards, Garry Show quoteHide quote "Karl E. Peterson" wrote: > GS wrote: > > Can anyone tell me how I could get a browser app to display a specific page > > (by name or by indexID), using the API SendMessage function? > > Why do you want to use SendMessage, and what the heck is an IndexID wrt a webpage? > > At any rate, to fire off a web page in the default browser, it's as simple as: > > Private Sub HyperJump(ByVal URL As String) > Call ShellExecute(0&, vbNullString, URL, vbNullString, _ > vbNullString, vbNormalFocus) > End Sub > > More info: http://vb.mvps.org/samples/HyperJmp > -- > ..NET: It's About Trust! > http://vfred.mvps.org > > > "GS" <G*@discussions.microsoft.com> wrote in message You might be able to use the SDK with Declare statement. Just post some of news:55409C09-132B-454D-9A23-0D186E2F431B@microsoft.com... > He has a SDK API that's not > registerable (regsrver32 doesn't like it) and so I can't use it with VBA > projects. the declaration here. Thanks! This would require shipping the DLL with VB6 apps, but will it work
with VBA apps? Using SendMessage seems easier to me! Here's the DLL constants: // API public commands const HEC_EXITPUB = 0; // Exit program HEC_LOADPAGE = 1; // Load page with name HEC_BRINGTOFRONT = 2; // Bring to front HEC_LOADID = 3; // Load page with ID HEC_ISHEPUB = 4; // Internal use DLLname = 'HEAPI.DLL'; Here's the DLL functions: // * DLL import functions * function StartPublication(PathToPublication, Params:PChar): LongInt; cdecl; external DLLName; // Execute the command of the pub specified by ID. function ExecuteCommand(PubId: LongInt; Command: LongInt; Params1: PChar): LongInt;cdecl; external DLLName; // Launch a pub & execute a command immediately. Always starts a new session. function StartExecuteCommand(PathToPublication:PChar; Command: LongInt; Params1: PChar): LongInt;cdecl; external DLLName; Here's the procedures that call them: procedure HEDisplayPage(pagename: String); begin EnsurePubIsRunning; ExecuteCommand(CurrentAppID, HEC_LOADPAGE, PChar(pagename)); ExecuteCommand(CurrentAppID, HEC_BRINGTOFRONT, ''); end; procedure HEDisplayID(pageID: Integer); begin EnsurePubIsRunning; ExecuteCommand(CurrentAppID, HEC_LOADID, PChar(inttostr(pageID))); ExecuteCommand(CurrentAppID, HEC_BRINGTOFRONT, ''); end; Garry -- "GS" <G*@discussions.microsoft.com> wrote in message Unfortunately, the functions were exported with "cdecl", so you can't use news:ED9DE7FF-0919-4871-A560-FC65EEDBDD21@microsoft.com... > Thanks! This would require shipping the DLL with VB6 apps, but will it > work > with VBA apps? Using SendMessage seems easier to me! them in VB6/VBA. You can tell the author to just edit "cdecl" to "stdcall" in the function declaration and recompile. See this article: INFO: Visual Basic Requirements for Exported DLL Functions http://support.microsoft.com/kb/142840 Another option is to make a light weight C or Delphi wrapper DLL, which translates the calls. Here is an air code: // Original function function StartPublication(PathToPublication, Params:PChar): LongInt; cdecl; external DLLName; // This one is callable from VB function StartPublicationVB(PathToPublication, Params:PChar):LongInt; stdcall; begin // Call the original function Result := StartPublication(PathToPublication, Params); end; You can download Turbo C++ or Delphi 2006 freely from here: http://www.turboexplorer.com Thanks again!
I'll pass this on to the author to see if he'll respond. Here's what he sent me regarding the DLL: About the wMsg: it’s more complicated: below is the code used by the DLL to send data to the publication. function SendHEMessage(Window: THandle; Envoi: THEVCommand): LongInt; var CopyDataStruct: TCopyDataStruct; begin with CopyDataStruct do begin dwData := 1; cbData := sizeof(Envoi); lpData := @Envoi; end; Result := SendMessage(Window, WM_COPYDATA, HInstance, LONGINT(@CopyDataStruct)); end; // Echange données. PCopyDataStruct = ^TCopyDataStruct; TCopyDataStruct = record dwData: LongInt; cbData: LongInt; lpData: Pointer; end; Here are the two structures I mentioned: PHEVCommand = ^THEVCommand; THEVCommand = packed record Param1: string[255]; Param2: string[255]; Param3: LongInt; Command: integer; Sender: THandle; end; it works with pointers. AFAIR, VB doesn’t handle pointers (or maybe they changed this…)? Maybe you could make some VB sense of it. If you could I will be most appreciative! Garry -- "GS" <G*@discussions.microsoft.com> wrote in message See this article:news:8D0AF688-66D9-44C4-9168-E4D5B82AE096@microsoft.com... > Thanks again! > I'll pass this on to the author to see if he'll respond. > > Here's what he sent me regarding the DLL: How To Pass String Data Between Applications Using SendMessage http://support.microsoft.com/kb/176058 Show quoteHide quote > function SendHEMessage(Window: THandle; Envoi: THEVCommand): LongInt; Translation(air code):> > var > > CopyDataStruct: TCopyDataStruct; > > begin > > with CopyDataStruct do > > begin > > dwData := 1; > > cbData := sizeof(Envoi); > > lpData := @Envoi; > > end; > > Result := SendMessage(Window, WM_COPYDATA, HInstance, > LONGINT(@CopyDataStruct)); > > end; Function SendHEMessage(ByVal Window As Long, ByRef Envoi As THEVCommand) As Long Dim cds As TCopyDataStruct; cds.dwData = 1 cds.cbData = Len(Envoi) cds.lpData = VarPtr(Envoi) SendHEMessage = SendMessage(Window, WM_COPYDATA, App.hInstance, ByVal VarPtr(cds)) End Function > PCopyDataStruct = ^TCopyDataStruct; This is declared in the article.> > TCopyDataStruct = record > > dwData: LongInt; > > cbData: LongInt; > > lpData: Pointer; > > end; Show quoteHide quote > PHEVCommand = ^THEVCommand; Translation(air code):> > THEVCommand = packed record > > Param1: string[255]; > > Param2: string[255]; > > Param3: LongInt; > > Command: integer; > > Sender: THandle; > > end; Type THEVCommand Param1(1 To 255) As String Param2(1 To 255) As String Param3 As Long Command As Long Sender As Long End Type The 255 above could be 256, I am not sure. You will need to use CopyMemory() to copy from a VB String to the byte array. Example: CopyMemory ByVal VarPtr(Envoi.Param1(0), ByVal s, Len(s) + 1 Save your project often because you are likly to crash the IDE. > it works with pointers. AFAIR, VB doesn't handle pointers (or maybe they WM_COPYDATA can copy data between processes if needed.> changed this.)? More thanks!
I guess what I need to do is try to follow the flow path of the values being passed, starting with the entry point from the software procedure making the call to the DLL, and from there to the DLL making the call to SendMessage. Therein is where I will find a solution. Unfortunately, my programming skills are only 'entry level' and so this is way over my head. However, I have an appetite for learning and so I will persist. I really appreciate your assistance! Thanks so much... Kind regards, Garry -- Show quoteHide quote"Nobody" wrote: > "GS" <G*@discussions.microsoft.com> wrote in message > news:8D0AF688-66D9-44C4-9168-E4D5B82AE096@microsoft.com... > > Thanks again! > > I'll pass this on to the author to see if he'll respond. > > > > Here's what he sent me regarding the DLL: > > See this article: > > How To Pass String Data Between Applications Using SendMessage > http://support.microsoft.com/kb/176058 > > > function SendHEMessage(Window: THandle; Envoi: THEVCommand): LongInt; > > > > var > > > > CopyDataStruct: TCopyDataStruct; > > > > begin > > > > with CopyDataStruct do > > > > begin > > > > dwData := 1; > > > > cbData := sizeof(Envoi); > > > > lpData := @Envoi; > > > > end; > > > > Result := SendMessage(Window, WM_COPYDATA, HInstance, > > LONGINT(@CopyDataStruct)); > > > > end; > > Translation(air code): > > Function SendHEMessage(ByVal Window As Long, ByRef Envoi As THEVCommand) As > Long > Dim cds As TCopyDataStruct; > > cds.dwData = 1 > cds.cbData = Len(Envoi) > cds.lpData = VarPtr(Envoi) > SendHEMessage = SendMessage(Window, WM_COPYDATA, App.hInstance, ByVal > VarPtr(cds)) > End Function > > > > PCopyDataStruct = ^TCopyDataStruct; > > > > TCopyDataStruct = record > > > > dwData: LongInt; > > > > cbData: LongInt; > > > > lpData: Pointer; > > > > end; > > > This is declared in the article. > > > > PHEVCommand = ^THEVCommand; > > > > THEVCommand = packed record > > > > Param1: string[255]; > > > > Param2: string[255]; > > > > Param3: LongInt; > > > > Command: integer; > > > > Sender: THandle; > > > > end; > > Translation(air code): > > Type THEVCommand > Param1(1 To 255) As String > Param2(1 To 255) As String > Param3 As Long > Command As Long > Sender As Long > End Type > > The 255 above could be 256, I am not sure. You will need to use CopyMemory() > to copy from a VB String to the byte array. Example: > > CopyMemory ByVal VarPtr(Envoi.Param1(0), ByVal s, Len(s) + 1 > > Save your project often because you are likly to crash the IDE. > > > it works with pointers. AFAIR, VB doesn't handle pointers (or maybe they > > changed this.)? > > WM_COPYDATA can copy data between processes if needed. > > > > >
Show quote
Hide quote
"GS" <G*@discussions.microsoft.com> wrote in message Try using Spy++, which is part of VS6, in the VS6 Tools menu. If you don't news:CDEFE9C3-37D1-4E40-8E0D-76BCB93B500E@microsoft.com... > More thanks! > I guess what I need to do is try to follow the flow path of the values > being > passed, starting with the entry point from the software procedure making > the > call to the DLL, and from there to the DLL making the call to SendMessage. > Therein is where I will find a solution. > > Unfortunately, my programming skills are only 'entry level' and so this is > way over my head. However, I have an appetite for learning and so I will > persist. > > I really appreciate your assistance! Thanks so much... have it, use the following software: http://www.windows-spy.com Monitor the target application for WM_COPYDATA activity, and you will see what it's being sent to. On Tue, 12 May 2009 20:27:31 -0400, "Nobody" <nob***@nobody.com> Paul Caton (@PSC) has written some code to call *any* (or almost any)wrote: >Unfortunately, the functions were exported with "cdecl", so you can't use >them in VB6/VBA. You can tell the author to just edit "cdecl" to "stdcall" >in the function declaration and recompile. See this article: export from a DLL, no matter its export method. If the OP has trouble getting the author to create a stdcall version, there's always the other option. http://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=70195&lngWId=1 J. Jeremiah D. Seitz Omega Techware http://www.omegatechware.net Hello Jeremiah,
Thanks for your input. I can tell you for sure that the author has no intention of recompiling the DLL, not even to make it registerable.<??> I will look at this whether I get SendMessage working or not. Kind regards, Garry -- Show quoteHide quote"Jeremiah D. Seitz" wrote: > On Tue, 12 May 2009 20:27:31 -0400, "Nobody" <nob***@nobody.com> > wrote: > > >Unfortunately, the functions were exported with "cdecl", so you can't use > >them in VB6/VBA. You can tell the author to just edit "cdecl" to "stdcall" > >in the function declaration and recompile. See this article: > > Paul Caton (@PSC) has written some code to call *any* (or almost any) > export from a DLL, no matter its export method. If the OP has trouble > getting the author to create a stdcall version, there's always the > other option. > > http://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=70195&lngWId=1 > > J. > Jeremiah D. Seitz > Omega Techware > http://www.omegatechware.net > |
|||||||||||||||||||||||