Multi-page management for firefox using windows API

 Recently, due to the need of the project, some data display pages of the system are developed using web pages. The web page needs to be displayed like a dialog box. When it pops up, it can be placed on top of the first window on the desktop. You can customize each The size of the window. The browser uses the firefox browser packaged by a third-party company, which blocks the address bar and favorites bar, so it looks exactly the same as the dialog box. I happened to be watching the core programming of windows, and I took advantage of this project to practice my hands and become familiar with the windows API.

Use the following interface when creating a firefox process:

BOOL WINAPI CreateProcess(
  _In_opt_    LPCTSTR               lpApplicationName,
  _Inout_opt_ LPTSTR                lpCommandLine,
  _In_opt_    LPSECURITY_ATTRIBUTES lpProcessAttributes,
  _In_opt_    LPSECURITY_ATTRIBUTES lpThreadAttributes,
  _In_        BOOL                  bInheritHandles,
  _In_        DWORD                 dwCreationFlags,
  _In_opt_    LPVOID                lpEnvironment,
  _In_opt_    LPCTSTR               lpCurrentDirectory,
  _In_        LPSTARTUPINFO         lpStartupInfo,
  _Out_       LPPROCESS_INFORMATION lpProcessInformation
);

In the LPPROCESS_INFORMATION structure, there is information about the process being created, but there is no HWND of the window handle. Only through the window handle can the window size, display position and other information be set, and the following functions can be called:

BOOL WINAPI SetWindowPos(
  _In_     HWND hWnd,
  _In_opt_ HWND hWndInsertAfter,
  _In_     int  X,
  _In_     int  Y,
  _In_     int  cx,
  _In_     int  cy,
  _In_     UINT uFlags
);

Where uFlags is set to HWND_TOPMOST to ensure that the window is at the front of the Z-Order.

There is processId in the LPPROCESS_INFORMATION structure information. We can use enumwindows to traverse all windows to obtain the window handle HWND by judging whether the two process IDs are equal.

BOOL WINAPI EnumWindows(
  _In_ WNDENUMPROC lpEnumFunc,
  _In_ LPARAM      lParam
);

However, the firefox browser is a single process after the process is created. Even if the subsequent tab page is created using the createprocess method (with its own processId and threadId), it always only displays one in the task manager. Therefore, the above method cannot obtain the handle of the tab page (or new window) created later. But since windows has drawn this page, it must have a handle, so now we need to find a way to get this HWND.

The above enumwindows method is still used here, but the lpEnumFunc method needs to be modified, because the interface is created by me, so I know what the title of each window is. When traversing all windows, use getwindowtext to get the current traversed Title of HWND

int WINAPI GetWindowText(
  _In_  HWND   hWnd,
  _Out_ LPTSTR lpString,
  _In_  int    nMaxCount
);

Use GetWindowThreadProcessId to get the process ID of hwnd:

DWORD WINAPI GetWindowThreadProcessId(
  _In_      HWND    hWnd,
  _Out_opt_ LPDWORD lpdwProcessId
);

Compare whether its title and process number are consistent with firefox's process number and whether the browser title parameter we passed in is consistent, so that the HWND of the corresponding window can be obtained.

Another problem occurred during on-site deployment. There is another manufacturer on site. They also use firefox browser for data display. Of course, it is not our customized version, because we also use the npapi plug-in, so if someone else opens it first Their browser, and then open my browser through my interface, my window interface will indeed open, but it is created by someone else's browser executable, even if I explicitly write myself when using the createprocess method The executable path and configuration file path. The parameters of lpCommandLine are as follows:

-no -profile %profile path -new -tab

I Googled here for a long time, and I concluded that how to enable firefox multi-instance operation. The final conclusion is that this can be done. The parameters of lpCommandLine are as follows:

-no-remote -profile %profile path -new -tab

It is possible to open a new instance of firefox according to the set executable path, but the problem is that when you need to open another page, an error will be reported, because using the "-no-remote" parameter will lock the current configuration file, and my The plugin is in the profile, which means that I need to re-specify a profile path every time I open a new page, and the size of each profile is about 70m.

I can't think of a good solution for now.

to be continued.

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324971483&siteId=291194637