C言語でタスクバープログレス
C言語で、Windows のタスクバーにプログレス表示する小さいデモ。以下のコードをビルドする。
ole32.dll の API を使っているので、gcc なら -lole32
オプションを付けて libole32.a をリンクする。VC++ なら ole32.lib
をリンカオプションに付けてリンクする。
#include <windows.h> #include <shobjidl.h> void SetTBP(HWND hwnd) { ITaskbarList3 *ppv; CLSID clsid; IID iid; CLSIDFromString(OLESTR("{56FDF344-FD6D-11d0-958A-006097C9A090}"), &clsid); IIDFromString(OLESTR("{EA1AFB91-9E28-4B86-90E9-9E9F8A5EEFAF}"), &iid); CoCreateInstance(&clsid, NULL, CLSCTX_ALL, &iid, (void **)&ppv); ppv->lpVtbl->SetProgressValue(ppv, hwnd, 50, 100); } int WINAPI WinMain(HINSTANCE hi, HINSTANCE hp, LPSTR cl, int cs) { SetTBP(CreateWindow("BUTTON", 0, WS_VISIBLE, 0, 0, 0, 0, 0, 0, 0, 0)); return MessageBox(0, 0, 0, 0); }
起動すると、小さいウィンドウとメッセージボックスが出てきて、小さいウィンドウのほうのタスクバーアイテムの左半分が緑色に染まる。
ただし、現時点で最新の gcc 4.8.1 ではコンパイルエラーになる。なぜならば、ヘッダファイル shobjidl.h の SetProgressValue のプロトタイプ宣言の引数部分が間違っているからだ。
132 行目に、
STDMETHOD(SetProgressValue)(THIS_ ULONGLONG,ULONGLONG) PURE;
とあるので、
STDMETHOD(SetProgressValue)(THIS_ HWND,ULONGLONG,ULONGLONG) PURE;
と書き換えるといい。
あるいは、#include <shobjidl.h>
の代わりに、以下のコードによって ITaskbarList3 および SetProgressValue を定義するという荒技もある。
#define INTERFACE ITaskbarList3 DECLARE_INTERFACE(INTERFACE) { void *p[9]; STDMETHOD(SetProgressValue)(THIS_ HWND, ULONGLONG, ULONGLONG); }; #undef INTERFACE
これでやる場合は、void *p[9];
とあるように、SetProgressValue の定義が、メモリアドレス的に考えて、4 byte 単位で上から 10 番目になるようにすればいいっぽい。CoCreateInstance 関数というのは、おそらくだが、構造体ポインタポインタを受け取ると、そのアドレスを 4 byte ずつずらしながら、関数アドレスを代入していっている。