Home > Archives > 2010-03

2010-03

気まぐれ Programming TIPS 【3】

【3】 マルチディスプレイ制御(C)

気まぐれに思いついた内容を、私個人としては備忘録的に殴り書いたりしたいという思いはある。

今回はマルチディスプレイ制御について。
PCに複数のディスプレイが接続されているときに、それらを制御する方法です。

●ディスプレイの情報を取得する
まず、接続されているディスプレイの情報を取得しなければならない。
ディスプレイ情報の取得にはEnumDisplayMonitors関数を使用する。
EnumDisplayMonitors関数は指定されたクリッピング領域とデバイスコンテキストの可視領域が交差して形成される領域と重なる部分のあるディスプレイモニタを列挙します。by MSDN

BOOL EnumDisplayMonitors (
HDC hdc, // ディスプレイデバイスコンテキストのハンドル
LPCRECT lprcClip, // クリッピング領域を指定
MONITORENUMPROC lpfnEnum, // コールバック関数へのポインタ
LPARAM dwData // コールバック関数に渡すデータ
);
なにやら取得するディスプレイの条件を指定できるようだが、今回はすべてのディスプレイを取得したいので、第1、第2引数をNULLにする。
第3引数は見つけたディスプレイに対し1度ずつ呼ばれるコールバック関数へのポインタ。第4引数はその関数へ渡すデータである。

コールバック関数の宣言はこんな感じ、
bool CALLBACK MonitorProc(HMONITOR hMonitor,HDC hdc,LPRECT lprcMonitor,LPARAM dwData);

次は、各ディスプレイの情報を取得する。
取得にはGetMonitorInfo関数を使用する。

BOOL GetMonitorInfo(
HMONITOR hMonitor, // ディスプレイモニタのハンドル
LPMONITORINFO lpmi // ディスプレイモニタの情報へのポインタ
);
取得できる情報は下記構造体。

typedef struct tagMONITORINFO
{
DWORD cbSize; //構造体のサイズ
RECT rcMonitor; //ディスプレイ矩形のRECT構造体
RECT rcWork; //ディスプレイの有効面を表すRECT構造体
DWORD dwFlags; //ディスプレイのフラグ
} MONITORINFO, *LPMONITORINFO;
RECTのデータは仮想ディスプレイのもの。
複数のディスプレイが接続されていると、仮想的に1つのでかいディスプレイとして扱われるらしい。その中での位置とサイズ。

GetMonitorInfo関数で情報を取得するにはディスプレイのハンドルが必要である。
上記コールバック関数は各ディスプレイのハンドルを与えてくれるので、コールバック関数の中で、情報を取得する。

bool CALLBACK MonitorProc(HMONITOR hMonitor,HDC hdc,LPRECT lprcMonitor,LPARAM dwData)
{
    MONITORINFO mi;
   
    //MONITORINFO構造体のサイズを指定してやる.お約束 .これやらないとうまくいかない.
    mi.cbSize = sizeof(MONITORINFO);   

    GetMonitorInfo(hMonitor,&mi); 

    printf("monitor size %d * %d\n",mi.rcMonitor.right - mi.rcMonitor.left,mi.rcMonitor.bottom - mi.rcMonitor.top);
}

すべてのディスプレイについて上記コールバック関数が呼ばれるので、取得したMONITORINFOをどこかに記録しておけばあとで利用できる。
例えば、各ディスプレイにウィンドウを表示したい場合、MONITORINFOから仮想ディスプレイの座標がわかるのでその位置にMoveWindowなりしてやればよい。

文責:T.Sato

  • Comments (Close): 0
  • Trackbacks (Close): 0

Home > Archives > 2010-03

Search
Feeds
Meta

Return to page top