Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**
- * An old "scroll-able log" I made when I first learnt Windows programming.
- * Very basic and not really useful, but took me a long time to figure out
- * the auto size expansion, dynamic memory management, syncing, wide string stuff,
- * and so on, so want to keep it somewhere.
- *
- * Combined dsm-log.c and dsm-log.rc to save space and reduce contex switching
- */
- #include <windows.h>
- #include <stdio.h>
- #ifndef UNICODE
- #define UNICODE
- #endif
- #define N_SHOWN 1 /* how many messages to show at the same time */
- #define S_TEST L"[Hit Test a few times]"
- #define CLASS_LOGSCROLLABLE L"LogScrollable"
- #define MAX_LEN_MSG 32
- void *Zalloc(size_t len) {
- void *p = malloc(len);
- if (p==NULL) {
- perror("Error calling malloc()\n");
- }
- return(p);
- }
- void KlasWOld(HWND hWnd, CHAR *snle, size_t lenSnle) {
- WCHAR *sZof = Zalloc((lenSnle+1)*sizeof(WCHAR));
- MultiByteToWideChar(CP_UTF8, 0, snle, lenSnle, sZof, lenSnle);
- sZof[lenSnle] = '\0';
- SetWindowTextW(hWnd, sZof);
- free(sZof);
- }
- void KlasW(HWND hTarget, LPWSTR sMsg) {
- SetWindowTextW(hTarget, sMsg);
- }
- enum tag_TEST_ID {
- IDB_TEST_ADD_MSG = 101, IDB_TEST_CLEAR, IDB_TEST_EXIT
- };
- enum tag_LS_ID {
- IDB_PREV = 190, IDB_NEXT = 191, IDB_LAST = 192
- };
- enum tag_TAQ {
- L_WIDTH = 40, L_HEIGHT = 20, L_TEXT = 200,
- LS_X_CONTROLS = 10, LS_Y_CONTROL_TOP = 10 + N_SHOWN * L_HEIGHT,
- LS_X_MSGS = 10 + L_WIDTH, LS_Y_MSG_TOP = 10 + L_HEIGHT
- };
- /* -- tyeps -- */
- typedef struct tag_LOGSCROLLABLE {
- HWND hCurrent;
- HWND hCurIndex;
- HWND hButtonPrev;
- HWND hButtonNext;
- int index;
- BOOL isAutoScroll; /* auto-scroll on/of */
- int capMsgs; /* capacity */
- int nMsgs;
- LPWSTR *listMsgs;
- } LOGSCROLLABLE, *PLOGSCROLLABLE;
- void LS_Init(PLOGSCROLLABLE logData) {
- logData->capMsgs = 8;
- logData->index = 0;
- logData->isAutoScroll = TRUE;
- logData->nMsgs = 0;
- logData->listMsgs = (LPWSTR *) Zalloc((logData->capMsgs)*sizeof(LPVOID));
- printf("<LS I.> init'd\n");
- }
- void LS_Expand(PLOGSCROLLABLE logData) {
- printf("<LS E.> attempting to expand capacity...\n");
- int newCapMsgs = 3 * (logData->capMsgs) / 2;
- logData->listMsgs = (LPWSTR *) realloc(logData->listMsgs, newCapMsgs*sizeof(LPVOID));
- if (logData->listMsgs==NULL) { perror("realloc() failed\n"); }
- logData->capMsgs = newCapMsgs;
- printf("<LS E.> expanded capacity to %d\n", newCapMsgs);
- }
- void LS_CreateWindows(PLOGSCROLLABLE logData, HWND hWnd) {
- HINSTANCE hInst = (HINSTANCE) GetWindowLongPtr(hWnd, GWLP_HINSTANCE);
- logData->hCurrent = CreateWindowW(L"Static", S_TEST, WS_CHILD | WS_VISIBLE,
- LS_X_MSGS, LS_Y_MSG_TOP, L_TEXT, L_HEIGHT,
- hWnd, NULL, hInst, NULL);
- logData->hButtonPrev = CreateWindowW(L"Button", L"Prev", WS_CHILD | WS_VISIBLE,
- LS_X_CONTROLS, LS_Y_CONTROL_TOP+0*L_HEIGHT, L_WIDTH, L_HEIGHT,
- hWnd, (HMENU) IDB_PREV, hInst, NULL);
- logData->hCurIndex = CreateWindowW(L"Static", L"#", WS_CHILD | WS_VISIBLE,
- LS_X_CONTROLS, LS_Y_CONTROL_TOP+1*L_HEIGHT, L_WIDTH, L_HEIGHT,
- hWnd, NULL, hInst, NULL);
- logData->hButtonNext = CreateWindowW(L"Button", L"Next", WS_CHILD | WS_VISIBLE,
- LS_X_CONTROLS, LS_Y_CONTROL_TOP+2*L_HEIGHT, L_WIDTH, L_HEIGHT,
- hWnd, (HMENU) IDB_NEXT, hInst, NULL);
- CreateWindowW(L"Button", L"Latest", WS_CHILD | WS_VISIBLE,
- LS_X_CONTROLS, LS_Y_CONTROL_TOP+3*L_HEIGHT, L_WIDTH, L_HEIGHT,
- hWnd, (HMENU) IDB_LAST, hInst, NULL);
- CreateWindowW(L"Button", L"exit", WS_CHILD | WS_VISIBLE,
- 240, 0, 40, 20, hWnd, (HMENU) IDB_TEST_EXIT, NULL, NULL);
- CreateWindowW(L"Button", L"test", WS_CHILD | WS_VISIBLE,
- 240, 20, 40, 20, hWnd, (HMENU) IDB_TEST_ADD_MSG, NULL, NULL);
- printf("<LS C.W.> created windows\n");
- }
- void LS_Scroll(PLOGSCROLLABLE logData, WPARAM wParam) {
- if (logData->nMsgs==0) {
- return;
- }
- switch (wParam) {
- case IDB_PREV:
- logData->isAutoScroll = FALSE; /* auto-scroll off */
- logData->index--;
- break;
- case IDB_NEXT:
- logData->index++;
- break;
- case IDB_LAST:
- logData->isAutoScroll = TRUE; /* auto-scroll on */
- logData->index = logData->nMsgs - 1;
- break;
- default:
- /* need this to manually update sIndex */
- break;
- }
- if ((logData->index) < 0) {
- MessageBeep(MB_ICONWARNING);
- logData->index = 0;
- }
- if ((logData->index) > (logData->nMsgs)-1) {
- MessageBeep(MB_ICONWARNING);
- logData->index = logData->nMsgs - 1;
- }
- LPWSTR sIndex = (LPWSTR) Zalloc(10*sizeof(LPVOID));
- wsprintfW(sIndex, L"%d/%d", logData->index+1, logData->nMsgs);
- KlasW(logData->hCurIndex, sIndex);
- KlasW(logData->hCurrent, logData->listMsgs[logData->index]);
- free(sIndex);
- }
- void LS_AddMsg(PLOGSCROLLABLE logData, LPWSTR sMsg) {
- /* we need vwsprintf, right prlxvalue? */
- LPWSTR sMsgInList = (LPWSTR) Zalloc(MAX_LEN_MSG*sizeof(WCHAR));
- wcsncpy(sMsgInList, sMsg, MAX_LEN_MSG);
- sMsgInList[0] = (SHORT) (logData->nMsgs + 'B');
- /* too lazy to generate actually plausible messages */
- sMsgInList[MAX_LEN_MSG-1] = L'\0';
- logData->listMsgs[logData->nMsgs] = sMsgInList;
- logData->nMsgs++;
- LS_Scroll(logData, (WPARAM) 0); /* set new text */
- if (logData->isAutoScroll) {
- logData->index++;
- }
- if ((logData->nMsgs) > (logData->capMsgs - 5)) {
- LS_Expand(logData);
- }
- //for (int i=0; i<logData->nMsgs; i++) {
- //wprintf(L"%p is %s\n", logData->listMsgs[i], logData->listMsgs[i]);
- //}
- }
- void LS_Cleanup(PLOGSCROLLABLE logData) {
- for (int i=0; i<logData->nMsgs; i++) {
- if (logData->listMsgs[i]) {
- free(logData->listMsgs[i]);
- }
- }
- free(logData->listMsgs);
- free(logData);
- printf("<LS C.> Cleanup done!\n");
- }
- void LS_ButtonControl(PLOGSCROLLABLE logData, HWND hWnd, WPARAM wParam) {
- switch (wParam) {
- case IDB_PREV:
- case IDB_NEXT:
- case IDB_LAST:
- LS_Scroll(logData, wParam);
- break;
- case IDB_TEST_EXIT:
- SendMessageW(hWnd, WM_DESTROY, (WPARAM) NULL, (LPARAM) NULL);
- break;
- case IDB_TEST_ADD_MSG:
- LS_AddMsg(logData, L"*ary says hi");
- break;
- }
- }
- LRESULT CALLBACK WndProc(HWND hWnd, UINT wmsg, WPARAM wParam, LPARAM lParam) {
- static PLOGSCROLLABLE logData = NULL;
- switch (wmsg) {
- case WM_CREATE:
- logData = (PLOGSCROLLABLE) Zalloc(sizeof(LOGSCROLLABLE));
- LS_Init(logData);
- LS_CreateWindows(logData, hWnd);
- break;
- case WM_COMMAND:
- LS_ButtonControl(logData, hWnd, wParam);
- break;
- case WM_ERASEBKGND:
- break; /* allegd fix for flashing */
- case WM_DESTROY:
- LS_Cleanup(logData);
- PostQuitMessage(0);
- break;
- }
- return(DefWindowProcW(hWnd, wmsg, wParam, lParam));
- }
- int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpCmdLine, int nCmdShow) {
- WNDCLASSW wc = {0};
- wc.lpfnWndProc = WndProc;
- wc.hInstance = hInst;
- wc.lpszClassName = CLASS_LOGSCROLLABLE;
- RegisterClassW(&wc);
- HWND hWnd; /* "HWND hWnd;" indeed */
- hWnd = CreateWindowW(CLASS_LOGSCROLLABLE, L"Log", WS_OVERLAPPEDWINDOW,
- CW_USEDEFAULT, CW_USEDEFAULT, 300, 300, NULL, NULL, hInst, NULL);
- ShowWindow(hWnd, nCmdShow);
- MSG windowMsg = {0};
- while (GetMessage(&windowMsg, NULL, 0, 0)) {
- TranslateMessage(&windowMsg);
- DispatchMessage(&windowMsg);
- }
- return(0);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement