* acl4のページt0002
-(by [[K]], 2026.04.26)
** (1) 概要
-a4_t0002 は、 acl4v1 の1番目の補助ライブラリプログラムになります。
-補助ライブラリというのは、 acl4 ライブラリに加えられるほどきちんと書いてないけど、しかしそれなりには有用なのでライブラリ化はしておきたい、くらいの意味合いです。
-提供される主な機能は、以下の通りです。
--(1-1)WindowsのAPIを使ってグラフィックウィンドウを開いて描画する
** (2) デモ
-''[t0002a.c]:''
#define a_Version 1
#include <acl4v1.c>
#include <windows.h>
#include "a4_t0002.c"
int main()
{
a_Win win[1]; int c;
a_Win_ini(_a_ win, 256, 256, "graph", 0x000000);
for (c = 0; c < 256 * 256; c++)
win->buf[c] = c << 8;
a_Win_flushAll0(win);
Sleep(1000 * 10); // 10秒後に勝手に終了.
return 0;
}
-実行結果:
--
--https://essen.osask.jp/files/pic20260331a.png
** (3) ライブラリプログラム
// #include <windows.h> してあることが前提.
a_class(a_Win) {
char title[256];
int xsz, ysz;
uint32_t *buf;
HWND hWin;
HINSTANCE hInst;
BITMAPINFO bmi;
};
a_static a_Win *a_Win_opened = NULL;
a_static LRESULT CALLBACK a_Win_wndProc(HWND hw, unsigned int msg, WPARAM wp, LPARAM lp)
{
if (msg == WM_CLOSE) return 0; // closeボタンを無視.
if (msg == WM_DESTROY) { PostQuitMessage(0); return 0; }
a_Win *w = a_Win_opened;
if (w == NULL || w->hWin != hw)
return DefWindowProc(hw, msg, wp, lp);
if (msg == WM_PAINT) {
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hw, &ps);
SetDIBitsToDevice(hdc, 0, 0, w->xsz, w->ysz, 0, 0, 0, w->ysz, w->buf, &w->bmi, DIB_RGB_COLORS);
EndPaint(hw, &ps);
return 0;
}
return DefWindowProc(hw, msg, wp, lp);
}
a_static int a_Win_winThread(a_Win *w)
{
WNDCLASSEX wc;
RECT r;
int i;
MSG msg;
wc.cbSize = sizeof (WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = a_Win_wndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = w->hInst;
wc.hIcon = (HICON) LoadImage(NULL, MAKEINTRESOURCE(IDI_APPLICATION), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED);
wc.hIconSm = wc.hIcon;
wc.hCursor = (HCURSOR) LoadImage(NULL, MAKEINTRESOURCE(IDC_ARROW), IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED);
wc.hbrBackground = (HBRUSH) COLOR_APPWORKSPACE;
wc.lpszMenuName = NULL;
wc.lpszClassName = w->title;
if (RegisterClassEx(&wc) == 0) return 1;
r.left = 0; r.top = 0;
r.right = w->xsz; r.bottom = w->ysz;
AdjustWindowRect(&r, WS_OVERLAPPEDWINDOW & ~WS_THICKFRAME & ~WS_MAXIMIZEBOX, FALSE);
w->hWin = CreateWindowA(wc.lpszClassName, w->title, WS_OVERLAPPEDWINDOW & ~WS_THICKFRAME & ~WS_MAXIMIZEBOX,
CW_USEDEFAULT, CW_USEDEFAULT, r.right - r.left, r.bottom - r.top, NULL, NULL, w->hInst, NULL);
if (w->hWin == NULL) return 1;
ShowWindow(w->hWin, SW_SHOW);
UpdateWindow(w->hWin);
for (;;) {
i = GetMessage(&msg, NULL, 0, 0);
if (i == 0 || i == -1) break; // エラーもしくは終了メッセージ.
// そのほかはとりあえずデフォルト処理で.
TranslateMessage(&msg);
DispatchMessage(&msg);
}
UnregisterClass(w->title, w->hInst);
return 0;
}
a_static void a_Win_ini(_aDef_ a_Win *w, int xsz, int ysz, const char *title, uint32_t c)
{
#if (a_DbgLv >= 2)
if (xsz < 192 || ysz < 64)
a_errExit("%s(%d): Win_ini: bad window size: xsz=%d, ysz=%d", a_fil, a_lin, xsz, ysz);
if (title == NULL || strlen(title) == 0 || strlen(title) >= 256)
a_errExit("%s(%d): Win_ini: bad window title", a_fil, a_lin);
#endif
w->buf = a_malloc(_a_ xsz * ysz * sizeof (uint32_t));
int i;
for (i = 0; i < xsz * ysz; i++) { w->buf[i] = c; }
w->xsz = xsz; w->ysz = ysz;
strcpy(w->title, title);
w->bmi.bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
w->bmi.bmiHeader.biWidth = xsz;
w->bmi.bmiHeader.biHeight = - ysz;
w->bmi.bmiHeader.biPlanes = 1;
w->bmi.bmiHeader.biBitCount = 32;
w->bmi.bmiHeader.biCompression = BI_RGB;
a_Win_opened = w;
CreateThread(NULL, 0, (void *) a_Win_winThread, (void *) w, 0, (void *) &i);
Sleep(128);
}
a_static void a_Win_flushAll0(a_Win *w)
{
InvalidateRect(w->hWin, NULL, FALSE);
UpdateWindow(w->hWin);
}
** (99) 更新履歴
-2026.04.26(日) 初版