/*--------------------------------------------------------- WinTree2.0.3.0.cpp Use classes for data functions for data handling. UNICODE Not fully supported in 98, so TCHAR will be used instead of char, windows will convert to char. If using fully supporting UNICODE OPSYS then convert all string calls to UNICODE ws*** string handlers. This is standard Charles Petzold windows api starter. "All hale Petzold!" This is WinTree2.0.3.0 -> Windows Last Left Threaded Data Tree Version 2 0.3.0 It will be the first attempt to use child windows for data display, and point and click for tree member manipulation. ---------------------------------------------------------*/ #include #include "WinTree.h" // Holds classes, function definitions, and const. // Standard Petzold window WinMain... int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { static TCHAR szAppName[] = TEXT ("WinTree2_0_3_0") ; HWND hwnd ; MSG msg ; WNDCLASS wndclass ; HACCEL hAccel ; wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_NOCLOSE | CS_DBLCLKS ; wndclass.lpfnWndProc = WndProc ; wndclass.cbClsExtra = 0 ; wndclass.cbWndExtra = 0 ; wndclass.hInstance = hInstance ; wndclass.hIcon = LoadIcon (hInstance, MAKEINTRESOURCE (IDI_ICON)) ;// (NULL, IDI_APPLICATION) ; wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ; wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ; wndclass.lpszMenuName = szAppName; wndclass.lpszClassName = szAppName ; RegisterClass (&wndclass) ; unsigned long a[6] ; // use to give more memory space to the children. // Make changes to wndclass for the child windows. wndclass.lpfnWndProc = ChildWndProc ; wndclass.hCursor = LoadCursor (NULL, IDC_CROSS) ; wndclass.cbClsExtra = sizeof(a) ; wndclass.hIcon = NULL ; wndclass.lpszClassName = szChildClass ; // Now call Reg. again to register the child window type. RegisterClass (&wndclass) ; hwnd = CreateWindow (szAppName, TEXT ("Windows Last Left Threaded Tree 2.0.3.0"), WS_OVERLAPPEDWINDOW | WS_VSCROLL | WS_HSCROLL, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL) ; ShowWindow (hwnd, iCmdShow) ; UpdateWindow (hwnd) ; hAccel = LoadAccelerators (hInstance, szAppName) ; while (GetMessage (&msg, NULL, 0, 0)) { if(!TranslateAccelerator (hwnd, hAccel, &msg)) { TranslateMessage (&msg) ; DispatchMessage (&msg) ; } } return msg.wParam ; } // Petzold WndProc Modified... // +++++++++++++++++++++++++++++ BEGIN WinProc PROCEDURE +++++++++++++++++++++++ // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { static int cxChar, cxCaps, cyChar, cxClient, cyClient, iMaxWidth, xCaret, yCaret, cxIcon, cyIcon ; int iVertPos, iHorzPos, iPaintBeg, iPaintEnd, cxBlock, cyBlock, ix, iy, iz; static int iXCP, iYCP; static TCHAR szBuffer_8[12] ; // To hold x,y position. static TCHAR szBuffer_7[2] ; // To hold last node removed key value. static TCHAR szBuffer_6[2] ; static TCHAR szBuffer_5[2] ; static TCHAR szBuffer_4[99] ; static TCHAR szBuffer_3[2] ; // szBuffer_* used to hold output, and special messages. static TCHAR szBuffer_2[80] ; static TCHAR szBuffer_1[2] ; static TCHAR szBuffer[2] ; // szBuffer used in wsprintf TCHAR tC ; // Used in reading user input on node to remove. TCHAR* pC ; TCHAR* szBufferX[2] = {"a\0"} ; LPTSTR szAppName ; // Used in WndProc for MessageBox warning on Icon click close. HDC hdc ; PAINTSTRUCT ps ; // Standard Windows structors. TEXTMETRIC tm ; RECT rect ; SCROLLINFO si ; static HICON hIcon ; // To show Icon in client area. static HINSTANCE hInstance ; rect.left = cxChar * 36 ; // Screen coordinates use in InvalidateRect (hwnd, &rect, TRUE) ; rect.top = 0 ; rect.right = cxChar * 160 ; rect.bottom = cyChar * 10 ; static TreeNode *pRoot = CreateTree(); // Tree is made up out of these classes. static TreeData *pTD = new TreeData(pRoot); // Holds Tree data, pointer to root... static bool fDoesTreeExist = FALSE ; // Use these flags in the WM_ messages below. static bool fTreeDataChanged ; static bool fDrawHeaders = TRUE ; static bool fRemoveLestSigNode = FALSE ; static bool fShowCaret = FALSE ; // If tree data shown then show caret. static bool fNodeNotCurrentTreeMember = FALSE ; // If user enters a key value of a node that is not current in tree. static bool bLastLeftClick = FALSE ; // used to show or not show last position of cursor when LM click. int stop ; stop = 1 ; // Debug stop. switch (message) { case WM_CREATE: // Petzold standard simple windows stuff. // array of window handles for the child windows. static HWND hwndChild[ciNodeCount/2][ciRows] ; hdc = GetDC (hwnd) ; GetTextMetrics (hdc, &tm) ; cxChar = tm.tmAveCharWidth ; cxCaps = (tm.tmPitchAndFamily & 1 ? 3 : 2) * cxChar / 2 ; cyChar = tm.tmHeight + tm.tmExternalLeading ; ReleaseDC (hwnd, hdc) ; // Null out the szBuffer_*s at start up strcpy( szBuffer, "\0" ); strcpy( szBuffer_1, "\0" ); strcpy( szBuffer_2, "\0" ); strcpy( szBuffer_3, "\0" ); strcpy( szBuffer_4, "\0" ); strcpy( szBuffer_6, "\0" ); strcpy( szBuffer_7, "\0" ); // Save Max width needed for window. iMaxWidth = 26 * cxChar + 26 * cxCaps + 22 * cxCaps + strlen("Current Tree Data Members are..... : ") ; // To creat the 52 child windows. iz = 0 ; for (ix = 0 ; ix < (ciNodeCount/2); ++ix) { hwndChild[ix][0] = CreateWindow (szChildClass, NULL, WS_CHILDWINDOW | WS_VISIBLE, 0, 0, 0, 0, hwnd, (HMENU) iz, //(iy << 8 | ix), (HINSTANCE) GetWindowLong (hwnd, GWL_HINSTANCE), NULL) ; ++iz ; } for (ix = 0 ; ix < (ciNodeCount/2); ++ix) { hwndChild[ix][1] = CreateWindow (szChildClass, NULL, WS_CHILDWINDOW | WS_VISIBLE, 0, 0, 0, 0, hwnd, (HMENU) iz, //(iy << 8 | ix), (HINSTANCE) GetWindowLong (hwnd, GWL_HINSTANCE), NULL) ; ++iz ; } // End of 'for for' of child windows creat... // To get system time... SetTimer(hwnd, ID_TIMER, 1000, NULL) ; // To show Icon in client area. hInstance = ((LPCREATESTRUCT) lParam)->hInstance ; hIcon = LoadIcon (hInstance, MAKEINTRESOURCE (IDI_ICON)) ; return 0 ; case WM_SIZE: cxClient = LOWORD (lParam) ; cyClient = HIWORD (lParam) ; // Set vertical scroll bar range and page size si.cbSize = sizeof (si) ; si.fMask = SIF_RANGE | SIF_PAGE ; si.nMin = 0 ; si.nMax = NUMLINES + 1 ; si.nPage = cyClient / cyChar ; SetScrollInfo (hwnd, SB_VERT, &si, TRUE) ; // Set horizontal scroll bar range and page size si.cbSize = sizeof (si) ; si.fMask = SIF_RANGE | SIF_PAGE ; si.nMin = 0 ; si.nMax = 2 + iMaxWidth / cxChar ; si.nPage = cxClient / cxChar ; SetScrollInfo (hwnd, SB_HORZ, &si, TRUE) ; return 0 ; case WM_SETFOCUS: // Create and show the caret xCaret = cxChar * 47 ; yCaret = cyChar * 22 ; CreateCaret (hwnd, NULL, cxChar, cyChar); SetCaretPos (xCaret , yCaret ) ; ShowCaret (hwnd); return 0 ; case WM_KILLFOCUS: // hide and detroy the caret. HideCaret (hwnd) ; DestroyCaret () ; return 0 ; case WM_VSCROLL: // Get all the vertical scroll bar information si.cbSize = sizeof (si) ; si.fMask = SIF_ALL ; GetScrollInfo (hwnd, SB_VERT, &si) ; // Save the position for comparison later on iVertPos = si.nPos ; switch (LOWORD (wParam)) { case SB_TOP: si.nPos = si.nMin ; break ; case SB_BOTTOM: si.nPos = si.nMax ; break ; case SB_LINEUP: si.nPos -= 1 ; break ; case SB_LINEDOWN: si.nPos += 1 ; break ; case SB_PAGEUP: si.nPos -= si.nPage ; break ; case SB_PAGEDOWN: si.nPos += si.nPage ; break ; case SB_THUMBTRACK: si.nPos = si.nTrackPos ; break ; } // Set the position and then retrieve it. Due to adjustments // by Windows it might not be the same as the value set. si.fMask = SIF_POS ; SetScrollInfo (hwnd, SB_VERT, &si, TRUE) ; GetScrollInfo (hwnd, SB_VERT, &si) ; // If the position has changed, scroll the window and update it if (si.nPos != iVertPos) { ScrollWindow (hwnd, 0, cyChar * (iVertPos - si.nPos), NULL, NULL) ; UpdateWindow (hwnd) ; } return 0 ; case WM_HSCROLL: // Get all the vertical scroll bar information si.cbSize = sizeof (si) ; si.fMask = SIF_ALL ; // Save the position for comparison later on GetScrollInfo (hwnd, SB_HORZ, &si) ; iHorzPos = si.nPos ; switch (LOWORD (wParam)) { case SB_LINELEFT: si.nPos -= 1 ; break ; case SB_LINERIGHT: si.nPos += 1 ; break ; case SB_PAGELEFT: si.nPos -= si.nPage ; break ; case SB_PAGERIGHT: si.nPos += si.nPage ; break ; case SB_THUMBPOSITION: si.nPos = si.nTrackPos ; break ; default: break ; } // Set the position and then retrieve it. Due to adjustments // by Windows it might not be the same as the value set. si.fMask = SIF_POS ; SetScrollInfo (hwnd, SB_HORZ, &si, TRUE) ; GetScrollInfo (hwnd, SB_HORZ, &si) ; // If the position has changed, scroll the window if (si.nPos != iHorzPos) { ScrollWindow (hwnd, cxChar * (iHorzPos - si.nPos), 0, NULL, NULL) ; } return 0 ; case WM_RBUTTONUP: // For future use. break ; case WM_LBUTTONDOWN: // To find x,y coordinates of cursor. if(wParam & MK_LBUTTON) { iXCP = LOWORD(lParam); iYCP = HIWORD(lParam); bLastLeftClick = TRUE ; InvalidateRect (hwnd, &rect, TRUE) ; // This will force windows paint the output area of the client space. UpdateWindow(hwnd); // if left click on icon at bottom of user area then send 'ctrl' to exit. if( (iXCP > 176 && iXCP < 204) && (iYCP > 464 && iYCP < 496)) { szAppName = "\0"; // Must have a NULL terminated LPTSTR. (TCHAR* seems to work too, but maybe in the configuration only??? GetClassName(hwnd,szAppName, 32) ; // You need to get the window's class name. if( IDYES == MessageBox(hwnd, TEXT("Really want to close WinTree?"), szAppName, MB_YESNO|MB_ICONQUESTION) ) { wParam = VK_CONTROL ; message = WM_KEYDOWN ; SendMessage(hwnd, message, wParam, NULL ) ; } // 'if' inner most } // 'if' above } // 'if' top return 0 ; // WM_KEYDOWN // nVirtKey = (int) wParam; // virtual-key code // lKeyData = lParam; // key data case WM_CHAR: // To read in user's input on which node to remove. if( (wParam >= 65 && wParam <= 90) || (wParam >= 97 && wParam <= 122) ) { tC = (TCHAR) wParam ; pC = &tC ; strncpy( szBuffer, pC, 1 ) ; if( fDoesTreeExist = DoesTreeExist(pTD) ) // Check does tree exist function, if it does not exist, then { pTD->SetNodeToBeRemoved( szBuffer ) ; if( FetchNodeData( pTD ) ) { PreRemoveNode(pRoot, pTD, szBuffer_1, szBuffer_2, szBuffer_3, szBuffer_5, szBuffer_6, szBuffer_7, hwnd ) ; if( pTD->FetchPointerToRoot() != pRoot ) // If root node was removed/replaced reset WinProc's root pointer. pRoot = pTD->FetchPointerToRoot() ; } // End 'if' on "FetchNodeData" else { strcpy( pTD->FetchCurrentTreeMembers(), "Node Key Value Not Current Data Tree Member." ); // Yes this does work. strcpy( szBuffer_2, pTD->FetchCurrentTreeMembers() ); HideCaret (hwnd) ; DestroyCaret () ; } // End 'else' }// End 'if' on "fDoesTreeExist" InvalidateRect (hwnd, &rect, TRUE) ; UpdateWindow(hwnd); break ; } // End top 'if' int stop ; stop = 1 ; if( wParam != 32 ) { if( fDoesTreeExist = DoesTreeExist(pTD) ) strcpy( pTD->FetchCurrentTreeMembers(), "Node Key Value Not Legitimate." ); // Yes this does work. else strcpy( pTD->FetchCurrentTreeMembers(), "No Tree Exist!" ); // Yes this does work. strcpy( szBuffer_2, pTD->FetchCurrentTreeMembers() ); HideCaret (hwnd) ; DestroyCaret () ; InvalidateRect (hwnd, &rect, TRUE) ; UpdateWindow(hwnd); } break ; case WM_KEYDOWN: switch (wParam) { case VK_HOME: SendMessage (hwnd, WM_VSCROLL, SB_TOP, 0) ; break ; case VK_END: SendMessage (hwnd, WM_VSCROLL, SB_BOTTOM, 0) ; break ; case VK_PRIOR: SendMessage (hwnd, WM_VSCROLL, SB_PAGEUP, 0) ; break ; case VK_NEXT: SendMessage (hwnd, WM_VSCROLL, SB_PAGEDOWN, 0) ; break ; case VK_LEFT: // Left arrow key if( fDoesTreeExist = DoesTreeExist(pTD) ) // Check does tree exist function, if it does not exist, then { FetchAllTreeData(pTD) ; // This will load the data members of class TreeData pTD->SetPointerNodeToBeRemoved(pTD->FetchPointerLestSignificantNode()) ; // Sets node to be removed. PreRemoveNode(pRoot, pTD, szBuffer_1, szBuffer_2, szBuffer_3, szBuffer_5, szBuffer_6, szBuffer_7, hwnd ) ; // PreRemoveNode will call RemoveNode. if( pTD->FetchPointerToRoot() != pRoot ) // If root node was removed/replaced reset WinProc's root pointer. pRoot = pTD->FetchPointerToRoot() ; } InvalidateRect (hwnd, &rect, TRUE) ; // Force windows to repaint WinTree2's window so new data will be shown. UpdateWindow(hwnd); break ; case VK_UP: // Up arrow key. if( fDoesTreeExist = DoesTreeExist(pTD) ) // Check does tree exist function, if it does not exist, then { FetchAllTreeData(pTD) ; pTD->SetPointerNodeToBeRemoved( pTD->FetchPointerToRoot() ) ; PreRemoveNode(pRoot, pTD, szBuffer_1, szBuffer_2, szBuffer_3, szBuffer_5, szBuffer_6, szBuffer_7, hwnd ) ; if( pTD->FetchPointerToRoot() != pRoot ) // If root node was removed/replaced reset WinProc's root pointer. pRoot = pTD->FetchPointerToRoot() ; } InvalidateRect (hwnd, &rect, TRUE) ; UpdateWindow(hwnd); break ; case VK_RIGHT: // Right arrow key. if( fDoesTreeExist = DoesTreeExist(pTD) ) // Check does tree exist function, if it does not exist, then { FetchAllTreeData(pTD) ; pTD->SetPointerNodeToBeRemoved(pTD->FetchPointerMostSignificantNode()) ; PreRemoveNode(pRoot, pTD, szBuffer_1, szBuffer_2, szBuffer_3, szBuffer_5, szBuffer_6, szBuffer_7, hwnd ) ; } InvalidateRect (hwnd, &rect, TRUE) ; UpdateWindow(hwnd); break ; case VK_DOWN: // Down arrow key. if( fDoesTreeExist = DoesTreeExist(pTD) ) // Check does tree exist function, if it does not exist, then { FetchAllTreeData(pTD) ; pTD->SetPointerNodeToBeRemoved(pTD->FetchPointerMedianNode()) ; PreRemoveNode(pRoot, pTD, szBuffer_1, szBuffer_2, szBuffer_3, szBuffer_5, szBuffer_6, szBuffer_7, hwnd ) ; } InvalidateRect (hwnd, &rect, TRUE) ; UpdateWindow(hwnd); break ; case VK_SPACE: // Space bar will fetch the current tree data. { strcpy( szBuffer_1, "\0" ); strcpy( szBuffer_2, "\0" ); strcpy( szBuffer_3, "\0" ); strcpy( szBuffer_5, "\0" ); strcpy( szBuffer_7, "\0" ); if( fDoesTreeExist = DoesTreeExist(pTD) ) // Check does tree exist function, if it does not exist, then { // no data to get. pTD->VoidOutCurrentTreeMembers() ; // pTD is pointer to class that is used to pick up all tree data. FetchAllTreeData(pTD) ; // null out the old tree data before you pick up the new. strcpy( szBuffer_1, ( ( pTD->FetchPointerToRoot() )->FetchTreeNodeData() ) ); // root data strcpy( szBuffer_2, pTD->FetchCurrentTreeMembers() ); // current tree data strcpy( szBuffer_3, ( (pTD->FetchPointerLestSignificantNode())->FetchTreeNodeData() ) ); // lest sig node strcpy( szBuffer_5, ( (pTD->FetchPointerMostSignificantNode())->FetchTreeNodeData() ) ); // most sig node strcpy( szBuffer_6, ( (pTD->FetchPointerMedianNode())->FetchTreeNodeData() ) ); // median node strcpy( szBuffer_7, ( (pTD->FetchLastNodeRemoved() ) ) ); // last node removed with this key value }else{ // Tree does not exist. strcpy( pTD->FetchCurrentTreeMembers(), "No Tree Exist!" ); // Yes this does work. strcpy( szBuffer_2, pTD->FetchCurrentTreeMembers() ); HideCaret (hwnd) ; DestroyCaret () ; }// End of if...else... fDrawHeaders = FALSE ; // SO only draw the new tree data... InvalidateRect (hwnd, &rect, TRUE) ; // This will force windows paint the output area of the client space. UpdateWindow(hwnd); break ; case VK_CONTROL : // Ctrl key will send to WinMain the WM_DESTROY message that will delete pTD and by that trip // TreeData's de-structor that will del out any remaining tree members. SendMessage (hwnd, WM_DESTROY, 0, 0 ) ; break ; } // End of VK_SPACE ... } // End of switch on wParam ... return 0 ; case WM_PAINT: hdc = BeginPaint (hwnd, &ps) ; // Get vertical scroll bar position si.cbSize = sizeof (si) ; si.fMask = SIF_POS ; GetScrollInfo (hwnd, SB_VERT, &si) ; iVertPos = si.nPos ; // Get horizontal scroll bar position GetScrollInfo (hwnd, SB_HORZ, &si) ; iHorzPos = si.nPos ; // Find painting limits iPaintBeg = max (0, iVertPos + ps.rcPaint.top / cyChar) ; iPaintEnd = min (NUMLINES - 1, iVertPos + ps.rcPaint.bottom / cyChar) ; // x = cxChar * (1 - iHorzPos) ; // y = cyChar * (i - iVertPos) ; // SetTextAlign (hdc, TA_RIGHT | TA_TOP) ; SetTextAlign (hdc, TA_LEFT | TA_TOP) ; // With the Headers in the 'if' app. only redraws them when the window is reformed, not when new data is displayed. // This save some time on redraw rate. TextOut (hdc, cxChar * 36, cyChar * (2 + iVertPos) , szBuffer_1, strlen( szBuffer_1 ) ) ; TextOut (hdc, cxChar * 36, cyChar * (9 + iVertPos) , szBuffer_2, strlen( szBuffer_2 ) ) ; TextOut (hdc, cxChar * 36, cyChar * (3 + iVertPos) , szBuffer_3, strlen( szBuffer_3 ) ) ; TextOut (hdc, cxChar * 36, cyChar * (4 + iVertPos) , szBuffer_5, strlen( szBuffer_5 ) ) ; TextOut (hdc, cxChar * 36, cyChar * (5 + iVertPos) , szBuffer_6, strlen( szBuffer_6 ) ) ; TextOut (hdc, cxChar * 36, cyChar * (7 + iVertPos) , szBuffer_7, strlen( szBuffer_7 ) ) ; // Draws the gauge that graphically represents the number of tree members left out of the original number. DrawMembersGauge(cxChar, cyChar, iVertPos, hwnd, pTD) ; //MoveToEx( hdc, cxChar * 36, cyChar * (28 + iVertPos), NULL ) ; //LineTo( hdc, cxChar * 88, cyChar * (28 + iVertPos) ); if(bLastLeftClick) // will show last left click position. { TextOut (hdc, cxChar * 36, cyChar * 1, szBuffer, wsprintf( szBuffer, TEXT("%5d,"), iXCP ) ) ; TextOut (hdc, cxChar * 43, cyChar * 1, szBuffer, wsprintf( szBuffer, TEXT("%5d."), iYCP ) ) ; }; if(pTD->FetchCurrentTreeMemberCount( ) > 0 ) // This way 0 value not shown. { TextOut (hdc, cxChar * 36, cyChar * 6, szBuffer, wsprintf( szBuffer, TEXT("%2d"), pTD->FetchCurrentTreeMemberCount( ) ) ) ; SendMessage (hwnd, WM_SETFOCUS, 0, 0) ; // Show caret when tree data shown. } else { SendMessage (hwnd, WM_KILLFOCUS, 0, 0) ; // Kill caret when "No Tree Exist!" } if(pTD->FetchTimeStampLNR().wYear) // 'pTD->FetchTimeStampLNR()' is pointer to the Windows time struc in TreeData { // if '.wYear' exist then print the time stamp. PrintTimeStamp(hdc, pTD, cxChar, cyChar, cxCaps); } if( fDrawHeaders ) { // fDrawHeaders Set to FALSE in the WM_RBUTTONUP: so headers not redrawn, any other window activity will redraw headers along with rest of window. TextOut (hdc, cxChar, cyChar * (1 + iVertPos), "Last Left Click at x, y position is.....:", strlen( "Last Left Click at x, y position is.....:" ) ) ; TextOut (hdc, cxChar, cyChar * (2 + iVertPos), "Current Tree Root Data Member is. : ", strlen( "Current Tree Root Data Member is. : " ) ) ; TextOut (hdc, cxChar, cyChar * (3 + iVertPos), "Lest Significant Node is.................. : ", strlen( "Lest Significant Node is.................. : " ) ) ; TextOut (hdc, cxChar, cyChar * (4 + iVertPos), "Most Significant Node is................. : ", strlen( "Most Significant Node is................. : " ) ) ; TextOut (hdc, cxChar, cyChar * (5 + iVertPos), "Median Node is............................... : ", strlen( "Median Node is............................... : " ) ) ; TextOut (hdc, cxChar, cyChar * (6 + iVertPos), "Current Number of Tree Members... :", strlen( "Current Number of Tree Members... :" ) ) ; TextOut (hdc, cxChar, cyChar * (7 + iVertPos), "Last Node Removed.........................:", strlen( "Last Node Removed.........................:" ) ) ; TextOut (hdc, cxChar, cyChar * (8 + iVertPos), "Last Node Removed @ system time:", strlen( "Last Node Removed @ system time:" ) ) ; TextOut (hdc, cxChar, cyChar * (9 + iVertPos), "Current Tree Data Members are..... : ", strlen( "Current Tree Data Members are..... : " ) ) ; TextOut (hdc, cxChar, cyChar * (15 + iVertPos), "Last Left Threaded Data Tree is created at application start.", strlen( "Last Left Threaded Data Tree is created at application start." ) ) ; TextOut (hdc, cxChar, cyChar * (16 + iVertPos), "Space Bar: display tree member information.", strlen("Space Bar: display tree member information." ) ) ; TextOut (hdc, cxChar, cyChar * (17 + iVertPos), "Left Arrow: remove lest significant tree member.", strlen("Left Arrow: remove lest significant tree member." ) ) ; TextOut (hdc, cxChar, cyChar * (18 + iVertPos), "Right Arrow: remove most significant tree member.", strlen("Right Arrow: remove most significant tree member." ) ) ; TextOut (hdc, cxChar, cyChar * (19 + iVertPos), "Up Arrow: remove root tree member.", strlen("Up Arrow: remove root tree member." ) ) ; TextOut (hdc, cxChar, cyChar * (20 + iVertPos), "Down Arrow: remove median tree member.", strlen("Down Arrow: remove median tree member." ) ) ; //TextOut (hdc, cxChar, cyChar * (22 + iVertPos), "To remove a specific node enter it's key value. -->", strlen("To remove a specific node enter it's key value. -->" ) ) ; TextOut (hdc, cxChar, cyChar * (22 + iVertPos), "To remove a specific node enter it's key value. --> ,or click on the child window displaying it key value", strlen("To remove a specific node enter it's key value. --> ,or click on the child window displaying it key value" ) ) ; TextOut (hdc, cxChar, cyChar * (25 + iVertPos), "Once the last data member is removed the tree no longer exist.", strlen( "Once the last data member is removed the tree no longer exist." ) ) ; TextOut (hdc, cxChar, cyChar * (27 + iVertPos), "Current Tree Members Gauge---------->", strlen("Current Tree Members Gauge---------->") ) ; TextOut (hdc, cxChar, cyChar * (30 + iVertPos), "Ctrl: To exit aplication.", strlen("Ctrl: To exit aplication.") ) ; // To draw grids for child windows... cxBlock = (cxCaps * 3)-1 ; cyBlock = cyChar * 2 ; for (ix = 0 ; ix < (ciNodeCount/2) ; ++ix) for (iy = 0 ; iy < ciRows ; ++iy) MoveWindow (hwndChild[ix][iy], ix * cxBlock + 3 , iy * cyBlock + (cyChar * (11 + iVertPos)) -6 , cxBlock, cyBlock, TRUE) ; // To show Icon in client area. DrawIcon (hdc, cxChar * strlen("Ctrl: To exit aplication."), cyChar * (29 + iVertPos), hIcon) ; } // End 'if' on fDrawHeaders.... fDrawHeaders = TRUE ; EndPaint (hwnd, &ps) ; // To Gray out memu items.. if( !(fDoesTreeExist = DoesTreeExist(pTD)) ) WinTreeCommand(hwnd, hInstance, wParam, lParam, fDoesTreeExist) ; return 0 ; case WM_COMMAND: // 273 or 0x111 fDoesTreeExist = DoesTreeExist(pTD) ; if( lParam == 0 ) WinTreeCommand(hwnd, hInstance, wParam, lParam, fDoesTreeExist) ; stop = 1; break ; case WM_DESTROY: delete pTD ; KillTimer(hwnd, ID_TIMER) ; PostQuitMessage (0) ; return 0 ; } // End of switch on message return DefWindowProc (hwnd, message, wParam, lParam) ; } // End WinProc ... // ---------------------- END WinProc PROCEDURE ------------------------------ // ---------------------------------------------------------------------------