List. 9. Struktura GOL_MSG
1 2 3 4 5 6 |
typedef struct { BYTE type; BYTE uiEvent; int param1; int param2; } GOL_MSG; |
Type – definiuje typ urządzenia w którym wygenerowane wiadomość (message). Możliwe typy urządzeń, to: TYPE_UNKNOW, TYPE_KEYBOARD, TYPE_TOUCHSCREEN i TYPE_MOUSE
uiEvent- rodzaj zdarzenia generowanego przez obiekt: EVENT_INVALID (zdarzenie błędne), EVENT_MOVE(przesunięcie), EVENT_PRESS(naciśnięcie), EVENT_STILLPRESS(ciągłe naciskanie), EVENT_RELEASE(zwolnienie), EVENT_KEYSCAN(skanowanie stanów klawiszy), EVENT_CHARCODE.
Definicja składowych param1 i param2 jest zależna od typu urządzenia. Na przykład dla ekranów dotykowych TYPE_TOUCHSCREEN zawierają współrzędne x,y , a dla typu TYPE_KEYBOARD param1 zawiera ID obiektu, a param2 znak kodu klawisza.
- Wewnątrz funkcji GOLMsg z wskaźnikiem do struktury GOL_MSG jako argumentem (listing 10) jest wykonywana pętla wykrywająca obiekt generujący wiadomość.
- Wykryty obiekt zwraca przekonwertowaną wiadomość w oparciu o parametry GOL Messager.
- Użytkownik może zmienić domyślną akcję zdefiniowaną przez bibliotekę w funkcji GOLMsgCallBack.
- Po wykonaniu akcji obiekt powinien być narysowany ponownie w zależności od swojego nowego stanu.
List. 10. Funkcja GOLMsg
void GOLMsg(GOL_MSG *pMsg)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
void GOLMsg(GOL_MSG *pMsg) { OBJ_HEADER *pCurrentObj; WORD translatedMsg; if(pMsg->uiEvent == EVENT_INVALID) return; pCurrentObj = _pGolObjects; while(pCurrentObj != NULL) { if(pCurrentObj->MsgObj) { translatedMsg = pCurrentObj->MsgObj(pCurrentObj, pMsg); if(translatedMsg != OBJ_MSG_INVALID) { if(GOLMsgCallback(translatedMsg, pCurrentObj, pMsg)) if(pCurrentObj->MsgDefaultObj) pCurrentObj->MsgDefaultObj(translatedMsg, pCurrentObj, pMsg); } } pCurrentObj = (OBJ_HEADER *)pCurrentObj->pNxtObj; } } |
Na listingu 11 pokazano pętlę, w której jest wywoływana funkcja GOLDraw, w której są sprawdzane stany obiektów i ewentualnie wykonywane jest rysowanie, sprawdzane jest czy z drivera ekranu dotykowego nie jest przesłana informacja (message) o nie wykonanej akcji (funkcja TouchGetMsg) i na końcu na podstawie tej informacji funkcja GOLMsg interpretuje ta wiadomość i przekazuje sterowanie do funkcji GOLMsgCallback (listing 12).
List. 11. Funkcja GOLMsgCallback
1 2 3 4 5 6 7 8 |
while(1) { if(GOLDraw()) // Rysuje obiekt z warstwy Obejct layer (GOL) { TouchGetMsg(&msg); // odbierz informacje (message) z panelu dodtykowego GOLMsg(&msg); } }//end while |
List. 12. Pętla obsługi graficznego interfejsu użytkownika
Przed wywołaniem tej pętli wszystkie używane obiekty graficzne muszą być utworzone.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
Przed wywołaniem tej pętli wszystkie używane obiekty graficzne muszą być utworzone. WORD GOLMsgCallback(WORD objMsg, OBJ_HEADER *pObj, GOL_MSG *pMsg) { WORD objectID; objectID = GetObjID(pObj); GDDDemoGOLMsgCallback(objMsg, pObj, pMsg); //funkcja obsługi zdarzeń z obiektów // Tutaj można dodać dodatkowy kod użytkownika ... return (1); } |
Pobranie informacji o wykonanej akcji przez użytkownika z wykorzystaniem ekranu dotykowego wykonuje funkcja TouchGetMsg (listing 13). Zależnie od odczytanych współrzędnych x i y oraz poprzednio odczytanych współrzędnych prevX i prevY jest modyfikowana składowa uiEvent struktury GOL_MSG.
List. 13. Funkcja odczytu wiadomości (message) z interfejsu ekranu dotykowego
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
void TouchGetMsg(GOL_MSG *pMsg) { static SHORT prevX = -1; static SHORT prevY = -1; SHORT x, y; x = TouchGetX(); y = TouchGetY(); pMsg->type = TYPE_TOUCHSCREEN; pMsg->uiEvent = EVENT_INVALID; if((x == -1) || (y == -1)) { y = -1; x = -1; } if((prevX == x) && (prevY == y) && (x != -1) && (y != -1)) { pMsg->uiEvent = EVENT_STILLPRESS; pMsg->param1 = x; pMsg->param2 = y; return; } if((prevX != -1) || (prevY != -1)) { if((x != -1) && (y != -1)) { // Move pMsg->uiEvent = EVENT_MOVE; } else { // Released pMsg->uiEvent = EVENT_RELEASE; pMsg->param1 = prevX; pMsg->param2 = prevY; prevX = x; prevY = y; return; } } else { if((x != -1) && (y != -1)) { // Pressed pMsg->uiEvent = EVENT_PRESS; } else { // No message pMsg->uiEvent = EVENT_INVALID; } } pMsg->param1 = x; pMsg->param2 = y; prevX = x; prevY = y; } |