という要望を持ったのだが。
- --window-position, --window-size などのコマンドラインオプションがまともに作用しない。
- JavaScript指定して調整する方法があるも、windowの体裁が変になる。
- プロファイルを別に指定するとオプションが効く風でもあるが、プロファイルが変わるとログインが面倒。
ということで、標準的な手順を断念。新規に起動したらいんじゃね?という事に。
Win32API の CreateProcess で chrome 直撃したらウィンドウが別に開いた。嬉しい。
悲報:CreateProcess の引数に渡す STARTUPINFO 構造体の座標・サイズ情報は有効に作用しない!
という訳で、新規に開いたウィンドウを自前で探索して移動してやろう!
やり方としてはもっとスマートな方法があるのやもしれんが、一先ずこれで。
- その時点で開いているChromeのウィンドウのhWndを記録しておく。
- CreateProcessでChromeを--new-windowオプションとURLを指定して開く。
- ちょっと待機する。(即時にはウィンドウが開かない)
- 再度ウィンドウを探索し、先に記録しておいたものと突合し、合致しないのが居たらそいつがルパン。
- 対象ウィンドウをMoveWindowでお好きな位置に。
汎用性を持たせた書き方をしたいんだけどパラメータを設定ファイルに持たせるのが賢いのかな…全指定はきちゃない気がする。
一応これで動くよってサンプルはこんなところ。
#include <iostream>
#include <tchar.h>
#include <windows.h>
#include <list>
const TCHAR CHROME_PATH[] = _T( "C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe" );
struct TFindData {
std::list<HWND> chromeWnds;
bool bFound;
};
bool isChromeWindow( HWND hWnd, DWORD& dwProcessId ) {
bool bResult = false;
dwProcessId = 0;
DWORD dwThreadId = GetWindowThreadProcessId( hWnd, &dwProcessId );
HANDLE hProcess = OpenProcess( PROCESS_QUERY_LIMITED_INFORMATION, FALSE, dwProcessId );
if ( hProcess ) {
TCHAR buf[ MAX_PATH ] = {};
DWORD dwBufLength = MAX_PATH - 1;
if ( QueryFullProcessImageName( hProcess, 0, buf, &dwBufLength ) ) {
if ( !lstrcmpi( CHROME_PATH, buf ) ) {
bResult = true;
}
}
CloseHandle( hProcess );
}
return bResult;
}
BOOL CALLBACK EnumChromeWndProc( HWND hWnd, LPARAM lParam ) {
TFindData* pData = reinterpret_cast< TFindData* >( lParam );
DWORD dwProcessId = 0;
if ( isChromeWindow( hWnd, dwProcessId ) ) {
pData->chromeWnds.push_back( hWnd );
}
return TRUE;
}
void MoveChromeWnd( HWND hWnd ) {
MoveWindow( hWnd, 4380, 0, 740, 1440, TRUE );
}
BOOL CALLBACK MoveNewChromeWnd( HWND hWnd, LPARAM lParam ) {
TFindData* pData = reinterpret_cast< TFindData* >( lParam );
DWORD dwProcessId = 0;
if ( isChromeWindow( hWnd, dwProcessId ) ) {
for ( std::list<HWND>::iterator it = pData->chromeWnds.begin(); it != pData->chromeWnds.end(); it++ ) {
if ( *it == hWnd ) {
return TRUE;
}
}
MoveChromeWnd( hWnd );
pData->bFound = true;
return FALSE;
}
return TRUE;
}
int _tmain( int argc, TCHAR* argv[] ) {
setlocale( LC_ALL, "JAPANESE" );
TFindData data;
data.bFound = false;
BOOL bResult = FALSE;
bResult = EnumWindows( EnumChromeWndProc, reinterpret_cast< LPARAM >( &data ) );
STARTUPINFO si = {};
si.cb = sizeof( si );
PROCESS_INFORMATION pi = {};
TCHAR OPEN_TWITTER[] = _T( "\"C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe\" --new-window \"https://twitter.com/home\" \"https://bsky.app/\"\0\0" );
bResult = CreateProcess( NULL, OPEN_TWITTER, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi );
if ( !bResult ) {
return 0;
}
data.bFound = false;
for ( int i = 0; i < 5; i++ ) {
Sleep( 200 );
bResult = EnumWindows( MoveNewChromeWnd, reinterpret_cast< LPARAM >( &data ) );
if ( !bResult ) {
break;
}
if ( data.bFound ) {
break;
}
Sleep( 300 );
}
CloseHandle( pi.hThread );
CloseHandle( pi.hProcess );
return 0;
}