mirror of
https://gitea.nishi.boats/pyrite-dev/milsko
synced 2026-01-09 10:53:27 +00:00
git-svn-id: http://svn2.nishi.boats/svn/milsko/trunk@83 b9cfdab3-6d41-4d17-bbe4-086880011989
296 lines
6.8 KiB
C
296 lines
6.8 KiB
C
/* $Id$ */
|
|
#include <Mw/Milsko.h>
|
|
|
|
typedef struct userdata {
|
|
MwLL ll;
|
|
WNDPROC old;
|
|
} userdata_t;
|
|
|
|
static LRESULT CALLBACK wndproc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) {
|
|
userdata_t* u = (userdata_t*)GetWindowLongPtr(hWnd, GWLP_USERDATA);
|
|
|
|
if(u == NULL) return DefWindowProc(hWnd, msg, wp, lp);
|
|
|
|
if(msg == WM_PAINT) {
|
|
PAINTSTRUCT ps;
|
|
RECT rc;
|
|
HBITMAP hbmp;
|
|
HDC dc, hbdc;
|
|
|
|
GetClientRect(hWnd, &rc);
|
|
|
|
dc = GetDC(hWnd);
|
|
hbmp = CreateCompatibleBitmap(dc, rc.right - rc.left, rc.bottom - rc.top);
|
|
hbdc = CreateCompatibleDC(dc);
|
|
SelectObject(hbdc, hbmp);
|
|
ReleaseDC(hWnd, dc);
|
|
|
|
u->ll->hDC = hbdc;
|
|
MwLLDispatch(u->ll, draw);
|
|
|
|
dc = BeginPaint(hWnd, &ps);
|
|
StretchBlt(dc, 0, 0, rc.right - rc.left, rc.bottom - rc.top, hbdc, 0, 0, rc.right - rc.left, rc.bottom - rc.top, SRCCOPY);
|
|
EndPaint(hWnd, &ps);
|
|
|
|
DeleteDC(hbdc);
|
|
DeleteObject(hbmp);
|
|
} else if(msg == WM_LBUTTONDOWN) {
|
|
SetCapture(hWnd);
|
|
MwLLDispatch(u->ll, down);
|
|
InvalidateRect(hWnd, NULL, FALSE);
|
|
} else if(msg == WM_LBUTTONUP) {
|
|
SetCapture(NULL);
|
|
MwLLDispatch(u->ll, up);
|
|
InvalidateRect(hWnd, NULL, FALSE);
|
|
} else if(msg == WM_SIZE) {
|
|
MwLLDispatch(u->ll, resize);
|
|
} else if(msg == WM_ERASEBKGND) {
|
|
return 1;
|
|
} else if(msg == WM_NCHITTEST) {
|
|
return HTCLIENT;
|
|
} else if(msg == WM_DESTROY) {
|
|
MwLLDispatch(u->ll, close);
|
|
PostQuitMessage(0);
|
|
} else if(msg == WM_CLOSE) {
|
|
DestroyWindow(hWnd);
|
|
} else {
|
|
return (u->old == NULL) ? DefWindowProc(hWnd, msg, wp, lp) : CallWindowProc(u->old, hWnd, msg, wp, lp);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
MwLL MwLLCreate(MwLL parent, int x, int y, int width, int height) {
|
|
MwLL r = malloc(sizeof(*r));
|
|
userdata_t* u = malloc(sizeof(*u));
|
|
WNDCLASSEX wc;
|
|
|
|
memset(&wc, 0, sizeof(wc));
|
|
wc.cbSize = sizeof(WNDCLASSEX);
|
|
wc.style = CS_HREDRAW | CS_VREDRAW;
|
|
wc.lpfnWndProc = wndproc;
|
|
wc.cbClsExtra = 0;
|
|
wc.cbWndExtra = 0;
|
|
wc.hInstance = (HINSTANCE)GetModuleHandle(NULL);
|
|
wc.lpszClassName = "milsko";
|
|
wc.lpszMenuName = NULL;
|
|
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
|
|
wc.hbrBackground = GetSysColorBrush(COLOR_MENU);
|
|
wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
|
|
wc.hIconSm = NULL;
|
|
|
|
MwLLCreateCommon(r);
|
|
|
|
RegisterClassEx(&wc);
|
|
|
|
r->hWnd = CreateWindow(parent == NULL ? "milsko" : "STATIC", "Milsko", parent == NULL ? (WS_OVERLAPPEDWINDOW) : (WS_CHILD | WS_VISIBLE), x, y, width, height, parent == NULL ? NULL : parent->hWnd, 0, wc.hInstance, NULL);
|
|
|
|
u->ll = r;
|
|
if(parent == NULL) {
|
|
u->old = NULL;
|
|
} else {
|
|
u->old = (WNDPROC)SetWindowLongPtr(r->hWnd, GWLP_WNDPROC, (LONG_PTR)wndproc);
|
|
}
|
|
SetWindowLongPtr(r->hWnd, GWLP_USERDATA, (LONG_PTR)u);
|
|
|
|
if(parent == NULL) {
|
|
RECT rc;
|
|
|
|
rc.left = 0;
|
|
rc.top = 0;
|
|
rc.right = width;
|
|
rc.bottom = height;
|
|
AdjustWindowRect(&rc, GetWindowLongPtr(r->hWnd, GWL_STYLE), FALSE);
|
|
SetWindowPos(r->hWnd, NULL, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, SWP_NOMOVE);
|
|
|
|
ShowWindow(r->hWnd, SW_NORMAL);
|
|
UpdateWindow(r->hWnd);
|
|
|
|
InvalidateRect(r->hWnd, NULL, FALSE);
|
|
}
|
|
|
|
return r;
|
|
}
|
|
|
|
void MwLLDestroy(MwLL handle) {
|
|
MwLLDestroyCommon(handle);
|
|
|
|
DestroyWindow(handle->hWnd);
|
|
|
|
free(handle);
|
|
}
|
|
|
|
void MwLLPolygon(MwLL handle, MwPoint* points, int points_count, MwLLColor color) {
|
|
POINT* p = malloc(sizeof(*p) * points_count);
|
|
HPEN pen = CreatePen(PS_NULL, 0, RGB(0, 0, 0));
|
|
int i;
|
|
|
|
for(i = 0; i < points_count; i++) {
|
|
p[i].x = points[i].x;
|
|
p[i].y = points[i].y;
|
|
}
|
|
SelectObject(handle->hDC, color->brush);
|
|
SelectObject(handle->hDC, pen);
|
|
SetPolyFillMode(handle->hDC, ALTERNATE);
|
|
Polygon(handle->hDC, p, points_count);
|
|
|
|
DeleteObject(pen);
|
|
|
|
free(p);
|
|
}
|
|
|
|
MwLLColor MwLLAllocColor(MwLL handle, int r, int g, int b) {
|
|
MwLLColor c = malloc(sizeof(*c));
|
|
HDC dc = GetDC(handle->hWnd);
|
|
|
|
if(r > 255) r = 255;
|
|
if(g > 255) g = 255;
|
|
if(b > 255) b = 255;
|
|
if(r < 0) r = 0;
|
|
if(g < 0) g = 0;
|
|
if(b < 0) b = 0;
|
|
|
|
c->brush = CreateSolidBrush(GetNearestColor(dc, RGB(r, g, b)));
|
|
c->red = r;
|
|
c->green = g;
|
|
c->blue = b;
|
|
|
|
ReleaseDC(handle->hWnd, dc);
|
|
|
|
return c;
|
|
}
|
|
|
|
void MwLLFreeColor(MwLLColor color) {
|
|
DeleteObject(color->brush);
|
|
|
|
free(color);
|
|
}
|
|
|
|
void MwLLGetXYWH(MwLL handle, int* x, int* y, unsigned int* w, unsigned int* h) {
|
|
RECT rc;
|
|
|
|
GetClientRect(handle->hWnd, &rc);
|
|
MapWindowPoints(handle->hWnd, GetParent(handle->hWnd), (LPPOINT)&rc, 2);
|
|
|
|
*x = rc.left;
|
|
*y = rc.top;
|
|
*w = rc.right - rc.left;
|
|
*h = rc.bottom - rc.top;
|
|
}
|
|
|
|
void MwLLSetXY(MwLL handle, int x, int y) {
|
|
SetWindowPos(handle->hWnd, NULL, x, y, 0, 0, SWP_NOSIZE);
|
|
InvalidateRect(handle->hWnd, NULL, FALSE);
|
|
}
|
|
|
|
void MwLLSetWH(MwLL handle, int w, int h) {
|
|
SetWindowPos(handle->hWnd, NULL, 0, 0, w, h, SWP_NOMOVE);
|
|
InvalidateRect(handle->hWnd, NULL, FALSE);
|
|
}
|
|
|
|
void MwLLSetTitle(MwLL handle, const char* title) {
|
|
SetWindowText(handle->hWnd, title);
|
|
}
|
|
|
|
int MwLLPending(MwLL handle) {
|
|
MSG msg;
|
|
|
|
(void)handle;
|
|
|
|
return PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) ? 1 : 0;
|
|
}
|
|
|
|
void MwLLNextEvent(MwLL handle) {
|
|
MSG msg;
|
|
|
|
(void)handle;
|
|
|
|
while(PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) {
|
|
GetMessage(&msg, NULL, 0, 0);
|
|
TranslateMessage(&msg);
|
|
DispatchMessage(&msg);
|
|
}
|
|
}
|
|
|
|
void MwLLSleep(int ms) {
|
|
Sleep(ms);
|
|
}
|
|
|
|
MwLLPixmap MwLLCreatePixmap(MwLL handle, unsigned char* data, int width, int height) {
|
|
MwLLPixmap r = malloc(sizeof(*r));
|
|
HDC dc = GetDC(handle->hWnd);
|
|
BITMAPINFOHEADER bmih;
|
|
RGBQUAD* quad = NULL;
|
|
int y, x;
|
|
|
|
r->width = width;
|
|
r->height = height;
|
|
|
|
bmih.biSize = sizeof(bmih);
|
|
bmih.biWidth = width;
|
|
bmih.biHeight = -(LONG)height;
|
|
bmih.biPlanes = 1;
|
|
bmih.biBitCount = 32;
|
|
bmih.biCompression = BI_RGB;
|
|
bmih.biSizeImage = 0;
|
|
bmih.biXPelsPerMeter = 0;
|
|
bmih.biYPelsPerMeter = 0;
|
|
bmih.biClrUsed = 0;
|
|
bmih.biClrImportant = 0;
|
|
|
|
r->hBitmap = CreateDIBSection(dc, (BITMAPINFO*)&bmih, DIB_RGB_COLORS, (void**)&quad, NULL, (DWORD)0);
|
|
|
|
for(y = 0; y < height; y++) {
|
|
for(x = 0; x < width; x++) {
|
|
RGBQUAD* q = &quad[y * width + x];
|
|
unsigned char* px = &data[(y * width + x) * 4];
|
|
q->rgbRed = px[0];
|
|
q->rgbGreen = px[1];
|
|
q->rgbBlue = px[2];
|
|
}
|
|
}
|
|
|
|
ReleaseDC(handle->hWnd, dc);
|
|
|
|
return r;
|
|
}
|
|
|
|
void MwLLDestroyPixmap(MwLLPixmap pixmap) {
|
|
DeleteObject(pixmap->hBitmap);
|
|
|
|
free(pixmap);
|
|
}
|
|
|
|
void MwLLDrawPixmap(MwLL handle, MwRect* rect, MwLLPixmap pixmap) {
|
|
HDC hmdc = CreateCompatibleDC(handle->hDC);
|
|
|
|
SelectObject(hmdc, pixmap->hBitmap);
|
|
|
|
SetStretchBltMode(handle->hDC, HALFTONE);
|
|
StretchBlt(handle->hDC, rect->x, rect->y, rect->width, rect->height, hmdc, 0, 0, pixmap->width, pixmap->height, SRCCOPY);
|
|
|
|
DeleteDC(hmdc);
|
|
}
|
|
|
|
void MwLLSetIcon(MwLL handle, MwLLPixmap pixmap) {
|
|
ICONINFO ii;
|
|
HICON ico;
|
|
HBITMAP mask;
|
|
|
|
mask = CreateBitmap(pixmap->width, pixmap->height, 1, 1, NULL);
|
|
|
|
memset(&ii, 0, sizeof(ii));
|
|
ii.fIcon = TRUE;
|
|
ii.xHotspot = 0;
|
|
ii.yHotspot = 0;
|
|
ii.hbmMask = mask;
|
|
ii.hbmColor = pixmap->hBitmap;
|
|
|
|
ico = CreateIconIndirect(&ii);
|
|
|
|
DeleteObject(mask);
|
|
|
|
SetClassLongPtr(handle->hWnd, GCLP_HICON, (LPARAM)ico);
|
|
|
|
DestroyIcon(ico);
|
|
}
|