/**************/ /* simplet.c */ /***************************************************************************** PROGRAM: simplet.c Windows: Vain Win 3.1 (miksi?) PURPOSE: Runko yksinkertaisille Windows-ohjelmille (joissa on vain yksi ikkuna). Ajatusta on jatkettu pitemmalle tiedostoissa tabhand.h ja tabhand.c. Kirjoitetaan tiedosto, jossa on käsittelyfunktiot esim. MyDraw (vaikkapa tiedostoon myown.c) MyCreate MyDown sekä viestitaulukko tMSGEntry MsgTbl[] = { { WM_PAINT , DoC, DoC, MyDraw , 1 }, { WM_LBUTTONDOWN , DoC, DoC, MyDown , 1 }, { WM_CREATE , DoC, DoC, MyCreate , 0 }, { 0 } }; ja tehdään projekti, jossa on tiedostot simplet.c myown.c simplet.def ja käännetään! Siinä se! Editor: Vesa Lappalainen 15.8.1992 & 16.6.1994 REMARK: Jos halutaan käsitellä viesti WM_DESTROY, pitää käsittelijä- funktiossa tehdä PostQuitMessage(0) tai paluttaa DEFRETURN DEFRETURN -paluuarvo aiheuttaa sen, että kutsutaan Windowsin oletuskäsittelijää (paitsi WM_DESTROY, joka kutsuu PostQuitMessage) TAULUKON YHDEN RIVIN SELITYS: { WM_LBUTTONDOWN , DoC, DoC, MyDown , 1 }, 1) 2) 3) 4) 5) 1) Viesti jolla kutsutaan mainittua funktiota. 2) wParam-muuttujan arvo viestissä jotta kutsu suoritetaan Kätevä esim. WM_COMMAND -viestin yhteydessä. DONT_CARE = arvoa ei tarkisteta (DoC) 3) lParam-muuttujan arvo jotta kutsu suoritetaan 4) Funktio jota kutsutaan em. ehtojen 1-3 täyttyessä 5) Tehdäänkö valmis hDC kutsua varten. (0=ei, 1 = kyllä) WM_PAINT viestissä tämä tehdään BeginPaint-kutsun avulla ja muulloin GetDC-kutsun avulla. Kutsun jälkeen hDC tuhotaan vastaavalla kutsulla. OMAT KÄSITTELYFUNKTIOT: Oma käsittelyfunktio on muotoa LONG MyCreate(tMSGParam *msg) { SetWindowText(msg->hWnd,WindowName); MoveWindow(msg->hWnd,10,10,600,500,FALSE); return NULL; } parametrissa msg on kentät: typedef struct { // Käsittelijälle tuotava tietue HWND hWnd; // Ikkunan kahva UINT message; // Viestin numero WPARAM wParam; // Viestin lyhyempi osa LPARAM lParam; // Viestin pisempi osa HDC hDC; // Mahdollisesti luotu laiteyhteys } tMSGParam; Paluuarvo on mikä tahansa viestin palautuksessa tarvittava arvo. DEFRETURN tarkoittaa, että pitää vielä kutsua Windowsin oletuskäsittelijää. Jos ikkunan oletuskoko tai otsikkoteksti halutaan muuttaa, pitää tämä tehdä esim. WM_CREATE -viestin käsittelijässä. EXAMPLE: Seuraavassa Hello World for Windows -esimerkki malliksi tiedostosta myown.c //---------------------------------------------------------------------------- #include #include "simplet.h" LONG MyDraw(tMSGParam *msg) { TextOut(msg->hDC, 10,10, "Hello World!",12); return NULL; } LONG MyCreate(tMSGParam *msg) { SetWindowText(msg->hWnd,"Hello World for Windows"); MoveWindow(msg->hWnd,10,10,300,200,FALSE); return NULL; } tMSGEntry MsgTbl[] = { { WM_PAINT , DoC, DoC, MyDraw ,1 }, { WM_CREATE , DoC, DoC, MyCreate ,0 }, { 0 } }; //---------------------------------------------------------------------------- *****************************************************************************/ #include /* Tarvitaan kaikissa Windows C-ohjelmissa */ #include "simplet.h" #define MAINWNAME "SimpleTClass" /* Tunniste, jolla ikkunaluokka tunnetaan */ char *WindowName = "Hello World!"; extern tMSGEntry MsgTbl[]; /****************************************************************************/ LONG FAR PASCAL _export MainWndProc(HWND hWnd, unsigned message, WPARAM wParam, LPARAM lParam) { tMSGEntry *m; for (m = MsgTbl; m->message; m++) /* Etsitään viestin käsittelijää */ if ( ( m->message == message || m->message == DONT_CARE ) && ( m->wParam == wParam || m->wParam == DONT_CARE ) && ( m->lParam == lParam || m->lParam == DONT_CARE ) ) { /* Löytyi haluttu käsittelijä */ PAINTSTRUCT ps; tMSGParam msg; LONG ret; msg.hWnd = hWnd; msg.message = message; msg.wParam = wParam; msg.lParam = lParam; msg.hDC = 0; if ( m->make_hDC ) { /* Tehdään valmis DC */ if ( message == WM_PAINT ) { if ( BeginPaint(hWnd,&ps) == NULL ) return NULL; msg.hDC = ps.hdc; } else if ( ( msg.hDC = GetDC(hWnd) ) == NULL ) return NULL; } /* Tehdään valmis DC */ ret = m->handler(&msg); if ( m->make_hDC ) /* poistetaan DC */ if ( message == WM_PAINT ) EndPaint(hWnd,&ps); else ReleaseDC(hWnd,msg.hDC); if ( ret != DEFRETURN ) return ret; break; } /* Löytyi haluttu käsittelijä */ switch (message) { case WM_DESTROY: /* Viesti: ikkuna hävitetään */ PostQuitMessage(0); return NULL; default: /* Antaa Windowsin käsitellä muut */ break; } return DefWindowProc(hWnd, message, wParam, lParam); } /****************************************************************************/ int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { WNDCLASS wc; /* Ikkunaluokka */ HWND hWnd; /* Pääikkunan kahva */ MSG msg; /* Viesti */ if (!lpCmdLine) lpCmdLine=NULL; /* Hämäystä, jottei valitusta param. */ if (!hPrevInstance) { /* Onko muita esiintymiä käynnissä? */ wc.style = NULL; wc.lpfnWndProc = MainWndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = GetStockObject(WHITE_BRUSH); wc.lpszMenuName = NULL; wc.lpszClassName = MAINWNAME; if (!RegisterClass(&wc)) return (FALSE); } hWnd = CreateWindow(MAINWNAME,WindowName,WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT, NULL,NULL,hInstance,NULL); if (!hWnd) return (FALSE); ShowWindow(hWnd, nCmdShow); /* Näytetään ikkuna */ UpdateWindow(hWnd); /* Lähetetään WM_PAINT viesti */ while (GetMessage(&msg,NULL,NULL,NULL)) { TranslateMessage(&msg); /* Tulkitaan virtuaaliset näp. koodit */ DispatchMessage(&msg); /* Lähetetään viesti ikkunalle */ } return (msg.wParam); /* Palautetaan PostQuitMessage-funktion arvo */ }