//
// ui-win.c
//
//
//
//-UserX 2002/03/24
#include <assert.h>
#include "misc/compat.h"
#include "ui/ui.h"
#include "ui/ui-win.h"
//todo: remove this dependence on iip/wingui.h (move offending variables into ui/ui-win)
#include "iip/wingui.h"
#include "base/mem.h"
#include "base/str.h"
#include "base/array.h"
#include "base/logger.h"
#include "crypt/random.h"
#include "msgcore/core.h"
/**
@author UserX
@name ui-win
*/
//@{
UIWinWindow blankuiwinwindow = {
{
NULL,
NULL,
(UIFuncUIWindowInit)uiwwInit,
(UIFuncUIWindowFree)uiwwFree,
(UIFuncUIWindowRun)uiwwRun,
(UIFuncUIControlSetState)uiwcSetState,
(UIFuncUIControlSetValue)uiwcSetValue,
(UIFuncUIEntryAdd)uiwwAddControl
},
0,
0,
NULL,
UIWIN_INACTIVE,
0,
0,
NULL,
0,
0,
0,
0,
0,
0
};
typedef struct UIWinHWND {
UIWinWindow *uiww;
HWND hwnd;
int visible;
} UIWinHWND;
typedef struct UIWinHWNDArrayHandle {
int size;
UIWinHWND *data;
} UIWinHWNDArrayHandle;
#define WINCLASSSTRING "iipuiwin"
WNDCLASSEX *WinClass = NULL;
ATOM WinClassAtom;
UIWinHWNDArrayHandle *uiwha = NULL;
UIWinHWND blankuiwh = {NULL, NULL, 0};
enum ID_ {
ID_BUTTON_UIGE_OK = 1
};
UIEntry uiwgetentropy[] = {
{UITYPE_TEXT, 0, "", NULL},
{UITYPE_TEXT, 0, N_("Please move the mouse and or press random keys."), NULL},
{UITYPE_TEXT, 0, N_("Click OK once done."), NULL},
{UITYPE_BUTTONOK, ID_BUTTON_UIGE_OK, N_("OK"), NULL}, //(UIFuncNotifyUIControl2) uiwgeNotify},
BLANKUIENTRY
};
void uiwhAdd(UIWinWindow *uiww, HWND hwnd) {
int i;
if(uiwha == NULL) {
uiwha = (UIWinHWNDArrayHandle *)arrayMake(sizeof(UIWinHWND), 0, &blankuiwh, NULL, NULL);
}
i = uiwha->size;
arrayInsert((ArrayHandle *)uiwha, i, 1);
uiwha->data[i].uiww = uiww;
uiwha->data[i].hwnd = hwnd;
}
void uiwhDelete(UIWinWindow *uiww) {
int i;
if(uiwha == NULL) {
return;
}
for(i = 0; i < uiwha->size; i++) {
if(uiwha->data[i].uiww == uiww) {
arrayDelete((ArrayHandle *)uiwha, i, 1);
break;
}
}
if(uiwha->size == 0) {
arrayFree((ArrayHandle *)uiwha);
uiwha = NULL;
}
}
UIWinWindow *uiwhFind(HWND hwnd) {
int i;
if(uiwha == NULL) {
return NULL;
}
for(i = 0; i < uiwha->size; i++) {
if(uiwha->data[i].hwnd == hwnd) {
return uiwha->data[i].uiww;
}
}
return NULL;
}
void uiwhShow(HWND hwnd) {
int i;
if(uiwha == NULL) {
return;
}
for(i = 0; i < uiwha->size; i++) {
if(uiwha->data[i].hwnd == hwnd) {
if(uiwha->data[i].visible == 0) {
ShowWindow(uiwha->data[i].hwnd, SW_SHOW);
uiwha->data[i].visible = 1;
}
}
}
return;
}
void uiwhHideOthers(HWND hwnd) {
int i;
if(uiwha == NULL) {
return;
}
for(i = 0; i < uiwha->size; i++) {
if(uiwha->data[i].hwnd != hwnd) {
ShowWindow(uiwha->data[i].hwnd, SW_HIDE);
uiwha->data[i].visible = 0;
}
}
return;
}
char *uiwGetClass(void) {
if(WinClass != NULL) {
return WINCLASSSTRING;
}
WinClass = memAlloc(sizeof(WNDCLASSEX), "UI-Win WinClass", WINCLASSSTRING);
WinClass->cbSize = sizeof(WNDCLASSEX);
WinClass->style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW | CS_NOCLOSE;// | CS_OWNDC;
//WinClass->lpfnWndProc = uiwwNotify;
WinClass->lpfnWndProc = uiwwcProc;
WinClass->cbClsExtra = 0;
WinClass->cbWndExtra = 0;
WinClass->hInstance = hinst;
WinClass->hIcon = LoadIcon(NULL, IDI_APPLICATION);
WinClass->hCursor = LoadCursor(NULL, IDC_ARROW);
WinClass->hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1); //(HBRUSH)GetStockObject(BLACK_BRUSH);
WinClass->lpszMenuName = NULL;
WinClass->lpszClassName = WINCLASSSTRING;
WinClass->hIconSm = LoadIcon(NULL, IDI_APPLICATION);
WinClassAtom = RegisterClassEx(WinClass);
assert(WinClassAtom != 0);
return WINCLASSSTRING;
}
UIWindow *uiwinMake(void) {
UIWinWindow *uiw;
uiw = memCopy(&blankuiwinwindow, sizeof(UIWinWindow), "UIWinWindow", NULL);
return (UIWindow *)uiw;
}
void uiwwInit(UIWinWindow *uiww) {
//HDC hdc;
//uiwGetClass();
/*uiww->hwnd = CreateWindowEx(WS_EX_APPWINDOW,
//uiww->hwnd = CreateWindow(
//(void *) WinClassAtom,
//uiwGetClass(),
WINCLASSSTRING,
//"isproxy",
uiww->uiw.caption,
WS_POPUPWINDOW | WS_CAPTION, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
NULL, NULL, hinst, NULL);
if(uiww->hwnd == NULL) {
DWORD err = GetLastError();
}
*/
//hdc = GetDC(uiww->hwnd);
//DeleteObject(SelectObject(hdc, GetStockObject(DEFAULT_GUI_FONT)));
//ReleaseDC(uiww->hwnd, hdc);
uiww->cstyle = DS_CENTER | DS_3DLOOK | DS_MODALFRAME | WS_CAPTION | WS_SYSMENU;
uiww->cexstyle = 0;
}
void uiwwFree(UIWinWindow *uiww) {
//todo: cycle through uica and release controls
DestroyWindow(uiww->hwnd);
uiwhDelete(uiww);
}
void uiwwRun(UIWinWindow *uiww) {
// RECT rect;
WORD *p;
LPCDLGTEMPLATE dialog;
int xmargin = 8;
int ymargin = 8;
int xx = 480;
int x = xx - xmargin * 2;
int y = ymargin;
int i = 0;
MSG msg;
uiwwSizeGroup(uiww, &i, &x, &y, xmargin, ymargin);
uiww->x = 0;
uiww->y = 0;
uiww->w = xx;
uiww->h = y;
/*
MoveWindow(uiww->hwnd, 0, 0, xx, y, TRUE);
GetClientRect(uiww->hwnd, &rect);
xx += xx - rect.right;
y += y - rect.bottom;
MoveWindow(uiww->hwnd, 0, 0, xx, y, TRUE);
ShowWindow(uiww->hwnd, SW_SHOW);
uiwhDelete(uiww);
uiwhAdd(uiww, uiww->hwnd);
uiww->active = UIWIN_ACTIVE;
while(uiww->active == UIWIN_ACTIVE) {
GetMessage(&msg, uiww->hwnd, 0, 0);
TranslateMessage(&msg);
DispatchMessage(&msg);
}
uiww->active = UIWIN_INACTIVE;
uiwhDelete(uiww);
ShowWindow(uiww->hwnd, SW_HIDE);
*/
//todo:centre window properly
//todo:adjust size to have proper inside area.
/*
rect.left = uiww->x;
rect.top = uiww->y;
rect.right = uiww->x + uiww->w;
rect.bottom = uiww->y + uiww->h;
AdjustWindowRectEx(&rect, uiww->cstyle, FALSE, uiww->cexstyle);
uiww->x = rect.left;
uiww->y = rect.top;
uiww->w = rect.right - rect.left;
uiww->h = rect.bottom - rect.top;
*/
// uiww->w += 8;
// uiww->h += 24;
p = uiwwToDialog(uiww);
dialog = (LPCDLGTEMPLATE) DWORDALIGN(p);
/*
uiwhAdd(uiww, NULL);
uiww->active = UIWIN_ACTIVE; //todo: move this into the notify function
//DialogBoxIndirect(hinst, dialog, NULL, uiwwNotify);
//todo: maybe: consider CreateDialogIndirect() instead
uiww->active = UIWIN_INACTIVE; //todo: move this into the notify function
uiwhDelete(uiww);
*/
uiwhAdd(uiww, NULL);
uiww->hwnd = CreateDialogIndirect(hinst, dialog, NULL, uiwwNotify);
//uiwhAdd(uiww, uiww->hwnd);
uiwhHideOthers(uiww->hwnd);
uiwhShow(uiww->hwnd);
//ShowWindow(uiww->hwnd, SW_SHOW);
uiww->active = UIWIN_ACTIVE;
while(uiww->active == UIWIN_ACTIVE) {
uiwhShow(uiww->hwnd);
GetMessage(&msg, NULL, 0, 0);//uiww->hwnd, 0, 0);
if(IsDialogMessage(uiww->hwnd, &msg) == 0) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
coreMainPoll(1);
}
uiww->active = UIWIN_INACTIVE;
ShowWindow(uiww->hwnd, SW_HIDE);
DestroyWindow(uiww->hwnd);
uiwhDelete(uiww);
memFree(p);
}
void uiwwSizeGroup(UIWinWindow *uiww, int *i, int *x, int *y, int xmargin, int ymargin) {
UIWinControl *uiwc;
int xx;
int cx;
int cy;
int cys;
int cw;
int ch;
HWND hwnd;
//for(; *i < uiww->uiw.uica->size; *i++) {
while(*i < uiww->uiw.uica->size) {
uiwc = (UIWinControl *) uiww->uiw.uica->data[*i];
cx = xmargin;
cy = *y;
cw = *x;//*x - xmargin * 2;
hwnd = uiwc->hwnd;
switch(uiwc->uic.entry.type) {
case UITYPE_BUTTON:
case UITYPE_BUTTONOK:
case UITYPE_BUTTONCANCEL:
cx += (cw - BUTTON_WIDTH) / 2;
cw = BUTTON_WIDTH;
ch = 32;//24;
(*y) += 4;
cy += 4;
cys = 4;
break;
case UITYPE_EDIT:
ch = 24;
cys = 4;
break;
case UITYPE_EDIT_LONG:
ch = 88;
cys = 4;
break;
case UITYPE_CHECK:
case UITYPE_RADIO:
ch = 16;
cys = 0;
break;
case UITYPE_TEXT:
ch = 16;
cys = 4;
break;
case UITYPE_BOXSTART:
ch = *y;
(*i)++;
(*y) += 20;
xx = *x - 16;
uiwwSizeGroup(uiww, i, &xx, y, xmargin + 8, ymargin);
ch = *y - cy + 4;
cys = -ch + 12;
break;
case UITYPE_COLUMN_START_2:
(*y) += 4;
(*i)++;
xx = cw / 2 - 8;
uiwwSizeGroup(uiww, i, &xx, y, xmargin, ymargin);
ch = *y - cy;
*y = cy + 4;
(*i)++;
uiwwSizeGroup(uiww, i, &xx, y, xmargin + cw / 2 + 8, ymargin);
if((*y - cy) > ch) {
ch = *y - cy;
}
*y = ch + cy + 4;
//todo:
break;
case UITYPE_COLUMN_STOP:
case UITYPE_BOXSTOP:
//(*i)++;
return;
case UITYPE_NONE:
case UITYPE_RADIOSTART:
case UITYPE_RADIOSTOP:
default:
cw = 0;
ch = 0;
cys = 0;
}
if(ch != 0 && uiwc->cclass != NULL) {
//MoveWindow(hwnd, cx, cy, cw, ch, TRUE);
uiwc->x = cx;
uiwc->y = cy;
uiwc->w = cw;
uiwc->h = ch;
(*y) += ch+ cys;
}
(*i)++;
}
}
void uiwwAddControl(UIWinWindow *uiww, UIEntry *uie) {
//HDC hdc;
UIEntry uiet;
UIWinControl *uiwc;
//LPCTSTR cclass = NULL;
char *cclass = NULL;
DWORD cestyle = 0;
DWORD cstyle = 0;
uiwc = memAlloc(sizeof(UIWinControl), "UIWinControl", NULL);
uieCopyAt(&uiwc->uic.entry, uie);
switch(uie->type) {
case UITYPE_BUTTON:
cclass = "BUTTON";
cstyle = BS_PUSHBUTTON | WS_TABSTOP;
break;
case UITYPE_BUTTONOK:
cclass = "BUTTON";
cstyle = BS_DEFPUSHBUTTON | WS_TABSTOP | WS_BORDER;
break;
case UITYPE_BUTTONCANCEL:
cclass = "BUTTON";
cstyle = BS_PUSHBUTTON | WS_TABSTOP;
break;
case UITYPE_EDIT:
uiet.caption = uie->caption;
uiet.type = UITYPE_TEXT;
uiet.id = 0;
uiet.notifyfunc = NULL;
uiwwAddControl(uiww, &uiet);
stringFree(uiwc->uic.entry.caption);
uiwc->uic.entry.caption = "";
cclass = "EDIT";
cstyle = WS_TABSTOP | WS_BORDER;
//cestyle = WS_EX_CLIENTEDGE;
break;
case UITYPE_EDIT_LONG:
uiet.caption = uie->caption;
uiet.type = UITYPE_TEXT;
uiet.id = 0;
uiet.notifyfunc = NULL;
uiwwAddControl(uiww, &uiet);
stringFree(uiwc->uic.entry.caption);
uiwc->uic.entry.caption = "";
cclass = "EDIT";
cstyle = ES_AUTOVSCROLL | ES_MULTILINE | WS_VSCROLL | WS_TABSTOP | WS_BORDER;
//cestyle = WS_EX_CLIENTEDGE;
break;
case UITYPE_CHECK:
cclass = "BUTTON";
cstyle = BS_AUTOCHECKBOX | WS_TABSTOP;
break;
case UITYPE_RADIO:
cclass = "BUTTON";
cstyle = BS_AUTORADIOBUTTON | WS_TABSTOP;
if(uiww->startradio != 0) {
cstyle |= WS_GROUP;
uiww->startradio = 0;
}
break;
case UITYPE_RADIOSTART:
uiww->startradio = 1;
break;
case UITYPE_RADIOSTOP:
break;
case UITYPE_TEXT:
cclass = "STATIC";
break;
case UITYPE_BOXSTART:
cclass = "BUTTON";
cstyle = BS_GROUPBOX;
break;
case UITYPE_COLUMN_START_2:
case UITYPE_COLUMN_STOP:
case UITYPE_BOXSTOP:
break;
case UITYPE_NONE:
break;
default:
LOGERROR(stringJoinMany("uiwwAddControl unhandle control type:", intToString(uiwc->uic.entry.type), NULL));
}
if(cclass != NULL) {
uiww->controlcount++;
uiwc->cclass = cclass;
uiwc->cstyle = cstyle | WS_VISIBLE | WS_CHILD;
uiwc->cexstyle = cestyle;
//todo: add control IDs
//uiwc->hwnd = CreateWindowEx(cestyle, cclass, uiwc->uic.entry.caption, cstyle | WS_VISIBLE | WS_CHILD, 0, 0, 80, 16, uiww->hwnd, NULL, hinst, NULL);
//hdc = GetDC(uiwc->hwnd);
//DeleteObject(SelectObject(hdc, GetStockObject(DEFAULT_GUI_FONT)));
//ReleaseDC(uiwc->hwnd, hdc);
/*
if(uiwc->uic.entry.id != 0) {
*/
//SetWindowLong(uiwc->hwnd, GWL_ID, uiwc->uic.entry.id + IDBASE);
/*
} else {
SetWindowLong(uiwc->hwnd, GWL_ID, IDBASE - 1);
}
*/
}
uicaAdd(uiww->uiw.uica, (UIControl *) uiwc);
}
WORD *uidtAddString(WORD *p, char *s) {
//todo: give this a better character limit (potential heap overflow)
return p + 1 + MultiByteToWideChar(CP_UTF8, 0, s, strlen(s), p, 512);
//return p + nCopyAnsiToWideChar(p, s);
}
WORD *uidtAddControl(WORD *p, UIWinControl *uiwc) {
*p++ = LOWORD (uiwc->cstyle);
*p++ = HIWORD (uiwc->cstyle);
*p++ = LOWORD (uiwc->cexstyle);
*p++ = HIWORD (uiwc->cexstyle);
*p++ = uiwc->x / 2; // x
*p++ = uiwc->y / 2; // y
*p++ = uiwc->w / 2; // cx
*p++ = uiwc->h / 2; // cy
*p++ = uiwc->uic.entry.id + IDBASE; // ID
//p = uidtAddString(p, uiwGetClass()); //class
p = uidtAddString(p, uiwc->cclass); //class
p = uidtAddString(p, uiwc->uic.entry.caption); //caption/text
*p++ = 0; // no extra data
return p;
}
void *uiwwToDialog(UIWinWindow *uiww) {
UIWinControl *uiwc;
WORD *p;
WORD *dialog;
int i;
if(uiww == NULL) {
return NULL;
}
//todo: change this to an accurate count of all controls and needed sizes (potential heap overflow)
p = memAlloc(1024 * (1 + uiww->controlcount), "uiwwDialog", NULL);
dialog = p;//todo: make this safer
p = DWORDALIGN(p);
*p++ = LOWORD (uiww->cstyle | DS_SETFONT);
*p++ = HIWORD (uiww->cstyle | DS_SETFONT);
*p++ = LOWORD (uiww->cexstyle);
*p++ = HIWORD (uiww->cexstyle);
*p++ = uiww->controlcount; // NumberOfItems
*p++ = uiww->x / 2; // x
*p++ = uiww->y / 2; // y
*p++ = uiww->w / 2; // cx
*p++ = uiww->h / 2; // cy
*p++ = 0; // Menu
*p++ = 0; // Class
//p = uidtAddString(p, uiwGetClass()); // Class
p = uidtAddString(p, uiww->uiw.caption); //Title
*p++ = 8; // PointSize
p = uidtAddString(p, "MS Sans Serif"); //FontName
for(i = 0; i < uiww->uiw.uica->size; i++) {
uiwc = (UIWinControl *)uiww->uiw.uica->data[i];
if(uiwc->cclass != NULL) {
p = DWORDALIGN(p);
p = uidtAddControl(p, uiwc);
}
}
return dialog;
}
int uiwcGetRadio(UIWinWindow *uiww, int index) {
int i;
UIWinControl *uiwc;
for(i = index; i >= 0 && uiww->uiw.uica->data[i]->entry.type != UITYPE_RADIOSTART; i--) {
uiwc = (UIWinControl *)uiww->uiw.uica->data[i];
if(SendMessage(uiwc->hwnd, BM_GETCHECK, 0, 0) == BST_CHECKED) {
return i;
}
}
for(i = index; i < uiww->uiw.uica->size && uiww->uiw.uica->data[i]->entry.type != UITYPE_RADIOSTOP; i++) {
uiwc = (UIWinControl *)uiww->uiw.uica->data[i];
if(SendMessage(uiwc->hwnd, BM_GETCHECK, 0, 0) == BST_CHECKED) {
return i;
}
}
return -1;
}
uiwcSetRadio(UIWinWindow *uiww, int index) {
int i;
UIWinControl *uiwc;
i = uiwcGetRadio(uiww, index);
if(i != -1) {
uiwc = (UIWinControl *)uiww->uiw.uica->data[i];
SendMessage(uiwc->hwnd, BM_SETCHECK, BST_UNCHECKED, 0);
}
uiwc = (UIWinControl *)uiww->uiw.uica->data[index];
SendMessage(uiwc->hwnd, BM_SETCHECK, BST_CHECKED, 0);
}
void uiwcSetState(UIWinWindow *uiww, int index, int state) {
UIWinControl *uiwc;
uiwc = (UIWinControl *)uiww->uiw.uica->data[index];
EnableWindow(uiwc->hwnd, (state != UISTATE_NORMAL) ? FALSE : TRUE);
}
void uiwcSetValue(UIWinWindow *uiww, int index) {
UIWinControl *uiwc;
uiwc = (UIWinControl *)uiww->uiw.uica->data[index];
switch(uiwc->uic.entry.type) {
case UITYPE_RADIO:
uiwcSetRadio(uiww, index);
break;
case UITYPE_CHECK:
SendMessage(uiwc->hwnd, BM_SETCHECK, (uiwc->uic.value != 0) ? BST_CHECKED : BST_UNCHECKED, 0);
break;
case UITYPE_EDIT:
case UITYPE_EDIT_LONG:
SetWindowText(uiwc->hwnd, uiwc->uic.stringvalue);
break;
}
}
//void uiwwDraw(UIWinWindow *uidw);
//int uiwwDoInput(UIWinWindow *uidw);
int uiwDialog(char *title, char *text, int type, int defaultchoice) {
int reply;
int mbtype;
int mbdef = 0;
defaultchoice &= type;
switch(type) {
case UIDIALOG_YESNO:
mbtype = MB_YESNO;
switch(defaultchoice) {
case UIDIALOG_NO:
mbdef = MB_DEFBUTTON2;
break;
case UIDIALOG_YES:
default:
mbdef = MB_DEFBUTTON1;
break;
}
break;
case UIDIALOG_YESNOCANCEL:
mbtype = MB_YESNOCANCEL;
switch(defaultchoice) {
case UIDIALOG_CANCEL:
mbdef = MB_DEFBUTTON3;
break;
case UIDIALOG_NO:
mbdef = MB_DEFBUTTON2;
break;
case UIDIALOG_YES:
default:
mbdef = MB_DEFBUTTON1;
break;
}
break;
case UIDIALOG_OKCANCEL:
mbtype = MB_OKCANCEL;
switch(defaultchoice) {
case UIDIALOG_CANCEL:
mbdef = MB_DEFBUTTON2;
break;
case UIDIALOG_OK:
default:
mbdef = MB_DEFBUTTON1;
break;
}
break;
case UIDIALOG_OK:
mbtype = MB_OK;
break;
default:
return 0;
}
reply = MessageBox(NULL, text, title, mbtype | mbdef);
switch(reply) {
case IDOK:
return UIDIALOG_OK;
case IDCANCEL:
return UIDIALOG_CANCEL;
case IDYES:
return UIDIALOG_YES;
case IDNO:
return UIDIALOG_NO;
}
return 0;
}
UIWinWindow *uiwwFromHWND(HWND hwnd) {
UIWinWindow *uiww;
for(;hwnd != NULL; hwnd = GetWindow(hwnd, GW_OWNER)) {
uiww = uiwhFind(hwnd);
if(uiww != NULL) {
return uiww;
}
}
return NULL;
}
int uiwcFindHWND(UIWinWindow *uiww, HWND hwnd) {
int i;
UIWinControl *uiwc;
for(i = 0; i < uiww->uiw.uica->size; i++) {
uiwc = (UIWinControl *)uiww->uiw.uica->data[i];
if(uiwc->hwnd == hwnd) {
return i;
}
}
return -1;
}
BOOL APIENTRY uiwwNotify(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
UIWinWindow *uiww;
int index;
UIWinControl *uiwc;
char *s;
int i;
int entropyvalue = 0;
if(message == WM_INITDIALOG) {
uiww = uiwhFind(NULL);
uiwhDelete(uiww);
uiwhAdd(uiww, hwnd);
//todo: do initialization stuff
for(i = 0; i < uiww->uiw.uica->size; i++) {
uiwc = (UIWinControl *)uiww->uiw.uica->data[i];
if(uiwc->uic.entry.id != 0) {
uiwc->hwnd = GetDlgItem(hwnd, IDBASE + uiwc->uic.entry.id);
}
}
for(i = 0; i < uiww->uiw.uica->size; i++) {
uiwc = (UIWinControl *)uiww->uiw.uica->data[i];
if(uiwc->hwnd != NULL) {
switch(uiwc->uic.entry.type) {
case UITYPE_RADIO:
if(uiwc->uic.value != 0) {
uiwcSetValue(uiww, i);
}
break;
case UITYPE_EDIT:
case UITYPE_EDIT_LONG:
case UITYPE_CHECK:
uiwcSetValue(uiww, i);
break;
}
uiwcSetState(uiww, i, uiwc->uic.state);
SetWindowLong(uiwc->hwnd, GWL_EXSTYLE, uiwc->cexstyle);
}
}
return TRUE;
}
uiww = uiwwFromHWND(hwnd);
if(uiww == NULL) {
//return DefWindowProc(hwnd, message, wParam, lParam);
return FALSE;
}
/*
index = uiwcFindHWND(uiww, hwnd);
if(index == -1) {
return DefWindowProc(hwnd, message, wParam, lParam);
} else {
uiwc = (UIWinControl *)uiww->uiw.uica->data[index];
}
*/
switch(message) {
case WM_MOUSEMOVE:
case WM_KEYUP:
entropyvalue = 1;
break;
default:
entropyvalue = 0;
break;
}
randomAddEntropy(message, 0);
randomAddEntropy(wParam, entropyvalue);
randomAddEntropy(lParam, entropyvalue);
randomAddEntropyClock(0);
if(uiww->entropyneed != 0) {
uiww->entropygot += entropyvalue;
if(uiww->entropygot >= uiww->entropyneed) {
uicEnable(&uiww->uiw, ID_BUTTON_UIGE_OK);
}
}
switch(message) {
case EN_KILLFOCUS:
case BN_CLICKED:
case WM_COMMAND:
if(LOWORD(wParam) == IDBASE - 1) {
index = -1;
} else {
index = uicaFind(uiww->uiw.uica, LOWORD(wParam) - IDBASE);
}
if(index == -1) {
//return DefWindowProc(hwnd, message, wParam, lParam);
return FALSE;
}
uiwc = (UIWinControl *)uiww->uiw.uica->data[index];
switch(message) {
case WM_COMMAND:
switch(uiwc->uic.entry.type) {
case UITYPE_BUTTON:
case UITYPE_BUTTONOK:
case UITYPE_BUTTONCANCEL:
//a kludge to do the entropy gathering
if(uiww->entropyneed != 0) {
uiww->active = UIWIN_INACTIVE;
EndDialog(hwnd, 0);
return TRUE;
}
if(uiwc->uic.entry.notifyfunc != NULL) {
if(uiwc->uic.entry.notifyfunc(uiww, uiwc, UINOTIFY_ACTIVATED) == UINOTIFYRETURN_EXIT) {
uiww->active = UIWIN_INACTIVE;
EndDialog(hwnd, 0);
}
}
return TRUE;
break;
/*
}
break;
case BN_CLICKED:
switch(uiwc->uic.entry.type) {
*/
case UITYPE_CHECK:
uiwc->uic.oldvalue = uiwc->uic.value;
uiwc->uic.value = (SendMessage(uiwc->hwnd, BM_GETCHECK, 0, 0) == BST_CHECKED) ? 1 : 0;
if(uiwc->uic.oldvalue != uiwc->uic.value) {
if(uiwc->uic.entry.notifyfunc != NULL) {
if(uiwc->uic.entry.notifyfunc(uiww, uiwc, UINOTIFY_CHANGE) == UINOTIFYRETURN_OK) {
//do nothing
} else {
uiwc->uic.value = uiwc->uic.oldvalue;
SendMessage(uiwc->hwnd, BM_SETCHECK, (uiwc->uic.value != 0) ? BST_CHECKED : BST_UNCHECKED, 0);
}
}
return TRUE;
}
break;
case UITYPE_RADIO:
//if((uiwc->uic.value != 0) && (!IsDlgButtonChecked(hwnd, uiwc->uic.entry.id + IDBASE))) {
if(!IsDlgButtonChecked(hwnd, uiwc->uic.entry.id + IDBASE)) {
break;
}
//todo: figure out currently checked radio
i = uicaClearRadioGroup(uiww->uiw.uica, index);
//uiwcSetRadio(uiww, index);
uiwc->uic.value = 1;
if(uiwc->uic.entry.notifyfunc != NULL) {
if(uiwc->uic.entry.notifyfunc(uiww, uiwc, UINOTIFY_CHANGE) == UINOTIFYRETURN_OK) {
//do nothing
} else {
uicaClearRadioGroup(uiww->uiw.uica, i);
uiwc = (UIWinControl *)uiww->uiw.uica->data[i];
uiwc->uic.value = 1;
uiwcSetRadio(uiww, i);
}
}
return TRUE;
break;
/*
}
break;
case EN_KILLFOCUS:
switch(uiwc->uic.entry.type) {
*/
case UITYPE_EDIT:
case UITYPE_EDIT_LONG:
uiwc->uic.oldstringvalue = uiwc->uic.stringvalue;
s = stringMake(GetWindowTextLength(uiwc->hwnd));
GetWindowText(uiwc->hwnd, s, GetWindowTextLength(uiwc->hwnd) + 1);
uiwc->uic.stringvalue = s;
if(stringCompare(uiwc->uic.oldstringvalue, uiwc->uic.stringvalue) == 0) {
stringFree(uiwc->uic.stringvalue);
uiwc->uic.stringvalue = uiwc->uic.oldstringvalue;
} else {
if(uiwc->uic.entry.notifyfunc != NULL) {
if(uiwc->uic.entry.notifyfunc(uiww, uiwc, UINOTIFY_CHANGE) == UINOTIFYRETURN_OK) {
stringFree(uiwc->uic.oldstringvalue);
} else {
stringFree(uiwc->uic.stringvalue);
uiwc->uic.stringvalue = uiwc->uic.oldstringvalue;
SetWindowText(uiwc->hwnd, uiwc->uic.stringvalue);
}
}
}
return TRUE;
break;
}
break;
/*
case UITYPE_COLUMN_START_2:
case UITYPE_COLUMN_STOP:
case UITYPE_RADIOSTART:
case UITYPE_RADIOSTOP:
case UITYPE_TEXT:
case UITYPE_BOXSTART:
case UITYPE_BOXSTOP:
case UITYPE_NONE:
break;
default:
LOGERROR(stringJoinMany("uiwwNotify unhandle control type:", intToString(uiwc->uic.entry.type), NULL));
}
*/
}
/*
case WM_NEXTDLGCTL:
i = 0;
break;
*/
default:
break;
}
//return DefWindowProc(hwnd, message, wParam, lParam);
return FALSE;
}
BOOL APIENTRY uiwwcProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
return DefWindowProc(hwnd, message, wParam, lParam);
}
int uiwGetEntropy(char *title, char *text, int bits) {
UIWindow *uiw;
UIWinWindow *uiww;
if(bits <= 0) {
return 0;
}
uiw = uiwMake(title);
uiwgetentropy[0].caption = text;
uiwAddControls(uiw, uiwgetentropy);
uiww = (UIWinWindow *)uiw;
uiww->entropyneed = bits;
uicDisable(&uiww->uiw, ID_BUTTON_UIGE_OK);
uiwRun(uiw);
bits = uiww->entropygot;
uiwFree(uiw);
return bits;
}
//@}
syntax highlighted by Code2HTML, v. 0.9.1