home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Interactive Guide / c-cplusplus-interactive-guide.iso / c_ref / csource1 / cenvew / whoryou.cmm < prev    next >
Encoding:
Text File  |  1993-12-20  |  12.0 KB  |  321 lines

  1. // WhoRYou.cmm - CEnvi demonstration for designing a dialog window.
  2. //               This demo prompts the user for information about
  3. //               themselves.  You can see from this sample code
  4. //               that dedigning your own windows and windows behavior
  5. //               is very flexible, but also complicated.
  6.  
  7. #include <Window.lib>
  8. #include <WinUtil.lib>
  9. #include <Message.lib>
  10.  
  11. main()
  12. {
  13.    do {
  14.       if ( GetUserID(FirstName,LastName,Sex) )
  15.          TryAgain = ShowOKmessage(FirstName,LastName,Sex);
  16.       else
  17.          TryAgain = ShowCancelMessage();
  18.    } while( TryAgain );
  19. }
  20.  
  21.  
  22. GetUserID(FirstName,LastName,Sex) // dialog box for user info
  23. {
  24.    // Initialize some size parameters
  25.    AveCharWidth, AveCharHeight;
  26.    GetCharacterSizes(AveCharWidth,AveCharHeight);
  27.    AveRowGap = AveCharHeight / 2;
  28.    AveColGap = AveCharWidth
  29.  
  30.    // Initially make the main window (which will be resized later).
  31.    // For now draw it off the screen so no one sees
  32.    MainWindow = MakeWindow(NULL,NULL,"GetUserIDFunc","Scientific Survey",
  33.                            WS_POPUPWINDOW | WS_CAPTION | WS_VISIBLE,
  34.                            -10,-10,9,9,NULL,uid);
  35.  
  36.    // Make a couple of lines of descriptive text
  37.    Description = "This scientifically-designed survery will determine if "
  38.                  "CEnvi is right for you.  Use a number 2 pencil.  "
  39.                  "Good luck! (no cheating)";
  40.    #define  MAX_TEXTLEN 40
  41.    DescRowCount = (strlen(Description) + 15/*wrap room*/) / MAX_TEXTLEN ;
  42.    MakeWindow(MainWindow,"static","GetUserIDChildFunc",Description,WS_CHILD | WS_VISIBLE,
  43.               AveColGap,AveRowGap,MAX_TEXTLEN * AveCharWidth,DescRowCount * AveCharHeight,NULL,uid);
  44.    BottomRow = AveRowGap + DescRowCount * AveCharHeight;
  45.  
  46.    // Request the user's first name, which is three fields
  47.    #define EDIT_MARGIN  (AveCharHeight / 4)  // extra space around edit field
  48.    BottomRow += AveRowGap;
  49.    prompt = "First Name";
  50.    EditLength = 22;  // default size of window for data input
  51.    MakeWindow(MainWindow,"static",NULL,prompt,WS_CHILD | WS_VISIBLE,
  52.               AveColGap,BottomRow + EDIT_MARGIN,
  53.               width = AveCharWidth * (strlen(prompt)+1),AveCharHeight,NULL);
  54.    MakeWindow(MainWindow,"static",NULL,NULL,WS_CHILD | WS_VISIBLE | SS_BLACKFRAME,
  55.               col = AveColGap * 2 + width,BottomRow,
  56.               (1+EditLength)*AveCharWidth,AveCharHeight + 2*EDIT_MARGIN,NULL);
  57.    uid.FirstNameHwnd = MakeWindow(MainWindow,"edit","GetUserIDChildFunc",NULL,
  58.          WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL | ES_LEFT,
  59.          col + AveCharWidth / 2,BottomRow + EDIT_MARGIN,
  60.          EditLength*AveCharWidth,AveCharHeight,NULL,uid);
  61.    BottomRow += AveCharHeight + 2*EDIT_MARGIN;
  62.  
  63.    // Request the user's last name, which is much like the first
  64.    BottomRow += AveRowGap;
  65.    prompt = "Last Name";
  66.    EditLength = 30;  // default size of window for data input
  67.    MakeWindow(MainWindow,"static",NULL,prompt,WS_CHILD | WS_VISIBLE,
  68.               AveColGap,BottomRow + EDIT_MARGIN,
  69.               width = AveCharWidth * (strlen(prompt)+1),AveCharHeight,NULL);
  70.    MakeWindow(MainWindow,"static",NULL,NULL,WS_CHILD | WS_VISIBLE | SS_BLACKFRAME,
  71.               col = AveColGap * 2 + width,BottomRow,
  72.               (1+EditLength)*AveCharWidth,AveCharHeight + 2*EDIT_MARGIN,NULL);
  73.    uid.LastNameHwnd = MakeWindow(MainWindow,"edit","GetUserIDChildFunc",NULL,
  74.          WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL | ES_LEFT,
  75.          col + AveCharWidth / 2,BottomRow + EDIT_MARGIN,
  76.          EditLength*AveCharWidth,AveCharHeight,NULL,uid);
  77.    BottomRow += AveCharHeight + 2*EDIT_MARGIN;
  78.  
  79.    // Add radio buttons to select sex
  80.    BottomRow += AveRowGap;
  81.    #define PUSHBUTT_HEIGHT AveCharHeight
  82.    width = AveCharWidth * (4 + strlen("Female"));
  83.    uid.FemaleHwnd = MakeWindow(MainWindow,"button","GetUserIDChildFunc","Female",WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON,
  84.               AveColGap * 3,BottomRow,width,PUSHBUTT_HEIGHT,NULL,uid);
  85.    uid.MaleHwnd = MakeWindow(MainWindow,"button","GetUserIDChildFunc","Male",WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON,
  86.               AveColGap * 4 + width,BottomRow,AveCharWidth * (4 + strlen("Male")),PUSHBUTT_HEIGHT,NULL,uid);
  87.    BottomRow += PUSHBUTT_HEIGHT;
  88.  
  89.    // Finally, add the OK and CANCEL buttons
  90.    BottomRow += AveRowGap * 2;
  91.    #define BUTTON_WIDTH  10 * AveCharWidth
  92.    #define BUTTON_HEIGHT AveCharHeight * 3 / 2
  93.    uid.OKhwnd = MakeWindow(MainWindow,"button","GetUserIDChildFunc","OK",
  94.               WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON | WS_DISABLED,
  95.               AveColGap * 3,BottomRow,BUTTON_WIDTH,BUTTON_HEIGHT,NULL,uid);
  96.    uid.CancelHwnd = MakeWindow(MainWindow,"button","GetUserIDChildFunc","CANCEL",WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
  97.               AveColGap * 6 + BUTTON_WIDTH,BottomRow,BUTTON_WIDTH,BUTTON_HEIGHT,NULL,uid);
  98.  
  99.  
  100.    SizeAndCenterDisplay(MainWindow,AveColGap,AveRowGap);
  101.  
  102.    // Initialize with FirstName as the active field
  103.    SetFocus(uid.FirstNameHwnd);
  104.    uid.OKselected = False;
  105.  
  106.    while ( DoWindows()  &&  !uid.OKselected ) ;
  107.  
  108.    if ( uid.OKselected ) {
  109.       GetEditText(uid.FirstNameHwnd,FirstName);
  110.       FirstName[0] = toupper(FirstName[0]);
  111.       GetEditText(uid.LastNameHwnd,LastName);
  112.       LastName[0] = toupper(LastName[0]);
  113.       if ( SendMessage(uid.FemaleHwnd,BM_GETCHECK,0,0) )    strcpy(Sex,"woman");
  114.       else if ( SendMessage(uid.MaleHwnd,BM_GETCHECK,0,0) ) strcpy(Sex,"man");
  115.       else                                                  strcpy(Sex,"person");
  116.       BreakWindow(MainWindow);
  117.       return(TRUE);
  118.    }
  119.  
  120.    return(FALSE);
  121. }
  122.  
  123.  
  124. /**** Windows functions called from GetUserInfo ****/
  125.  
  126. GetUserIDFunc(hwnd,msg,parm1,parm2,uid)
  127. {
  128.    if ( msg == WM_COMMAND ) {
  129.       childHwnd = parm2 & 0xFFFF;
  130.       switch ( (parm2 >> 16) & 0xFFFF ) {
  131.          case BN_CLICKED:
  132.             switch( childHwnd ) {
  133.                case uid.OKhwnd:
  134.                   uid.OKselected = TRUE;
  135.                   break;
  136.                case uid.CancelHwnd:
  137.                   BreakWindow(hwnd);
  138.                   break;
  139.                default:
  140.                   ShouldOKbeEnabled(uid);
  141.                   break;
  142.             }
  143.             break;
  144.          case EN_CHANGE:
  145.             ShouldOKbeEnabled(uid);
  146.             break;
  147.       }
  148.    }
  149. }
  150.  
  151. GetUserIDChildFunc(hwnd,msg,parm1,parm2,uid)
  152. {
  153.    #define VK_SHIFT  0x10
  154.  
  155.    if ( WM_CHAR == msg ) {
  156.       switch ( parm1 ) {
  157.          case '\t':
  158.             // Tab to next field or back tab to previous field.  Will allow moving
  159.             // to any field that is not "static" type and not disabled
  160.             Backward = (0x80 & DynamicLink("USER","GETKEYSTATE",SWORD16,PASCAL,VK_SHIFT));
  161.             Sibling = hwnd;
  162.             BLObSize(_className,40);
  163.             do {
  164.                // if this is the end of the list then go to the other end
  165.                if ( Sibling == GetWindow(Sibling,Backward ? GW_HWNDFIRST : GW_HWNDLAST ) )
  166.                   Sibling = GetWindow(Sibling,Backward ? GW_HWNDLAST : GW_HWNDFIRST );
  167.                else
  168.                   Sibling = GetWindow(Sibling,Backward ? GW_HWNDPREV : GW_HWNDNEXT);
  169.                _len = GetClassName(Sibling,_className,39);
  170.             } while( (_len == 6  &&  !memicmp(_className,"static",6))
  171.                   || !IsWindowEnabled(Sibling) );
  172.             SetFocus(Sibling);
  173.             return 0;
  174.          case ' ':
  175.             // don't let last name or first name accept spaces
  176.             if ( hwnd == uid.LastNameHwnd  ||  hwnd == uid.FirstNameHwnd )
  177.                return 0;
  178.             break;
  179.          case '\r';
  180.             // Enter selects the OK button, and so post a ' ' to the
  181.             // OK button window
  182.             if ( IsWindowEnabled(uid.OKhwnd) ) {
  183.                PostMessage(uid.OKhwnd,WM_KEYDOWN,' ',parm2);
  184.                PostMessage(uid.OKhwnd,WM_KEYUP,' ',parm2);
  185.             }
  186.             return(0);
  187.       }
  188.    }
  189. }
  190.  
  191.  
  192. ShouldOKbeEnabled(uid)  // adjust the OK button to be enabled or NOT
  193. {
  194.    WantOKstate = ( 0 != GetWindowTextLength(uid.FirstNameHwnd)
  195.                 && 0 != GetWindowTextLength(uid.LastNameHwnd)
  196.                 && ( SendMessage(uid.FemaleHwnd,BM_GETCHECK,0,0)
  197.                   || SendMessage(uid.MaleHwnd,BM_GETCHECK,0,0) ) );
  198.    EnableWindow(uid.OKhwnd,WantOKstate);
  199. }
  200.  
  201. /*** Message windows after user id form is complete ***/
  202. #include <MsgBox.lib>
  203.  
  204. ShowOKmessage(FirstName,LastName,Sex)
  205. {
  206.    sprintf(message,"%s %s:\rScientific analysis of your survey indicates that you "
  207.            "are a %s who knows a good shareware product when you see it.  "
  208.            "Numerological analyses show that you like to have complete "
  209.            "product manuals and you don't like registration-reminder "
  210.            "screens."
  211.            "\rRecommendation: You should register CEnvi right away."
  212.            "\r\rDo you want to try the survey again?",
  213.            FirstName,LastName,Sex);
  214.    return( IDYES == MessageBox(message,"SURVEY RESULTS",MB_YESNO) );
  215. }
  216.  
  217. ShowCancelMessage()
  218. {
  219.    return( IDYES == MessageBox(
  220.                "You did not complete the survey.  You are obviously in a hurry "
  221.                "to send in your CEnvi registration form."
  222.                "\r\rDo you want to try the survey again?",
  223.                "SURVEY CANCELED",MB_YESNO) );
  224. }
  225.  
  226. /*** UTILITIES CALLED BY THE ABOVE CODE ***/
  227.  
  228. SizeAndCenterDisplay(hwnd,RightMargin,BottomMargin)
  229. {
  230.    // Make the total size of this window fit around its children, with
  231.    // RightMargin and BottomMargin extra.  Then center this in the
  232.    // screen and display it.
  233.  
  234.    // Find maximum row and col of all children
  235.    ChildList = WindowList(hwnd);
  236.    assert( NULL != ChildList );
  237.    GetWindowRect(hwnd,ParentRect);
  238.    MaxChildCol = MaxChildRow = 0;
  239.    for ( i = GetArraySpan(ChildList); 0 <= i; i-- ) {
  240.       GetWindowRect(ChildList[i],ChildRect);
  241.       MaxChildCol = max(MaxChildCol,ChildRect.right - ParentRect.left);
  242.       MaxChildRow = max(MaxChildRow,ChildRect.bottom - ParentRect.top);
  243.    }
  244.  
  245.    // The window width and height must just be big enough for these
  246.    // maximums plus the margins and the window border
  247.    width = MaxChildCol + 1 + RightMargin + GetSystemMetrics(SM_CXBORDER);
  248.    height = MaxChildRow + 1 + BottomMargin + GetSystemMetrics(SM_CXBORDER);
  249.  
  250.    // Figure where to center this window in the screen
  251.    scrWidth = GetSystemMetrics(SM_CXSCREEN);
  252.    scrHeight = GetSystemMetrics(SM_CYSCREEN);
  253.    col = (ScrWidth - width) / 2;
  254.    row = (ScrHeight - height) / 2;
  255.  
  256.    MoveWindow(hwnd,col,row,width,height,TRUE);
  257. }
  258.  
  259. GetCharacterSizes(width,height)
  260. {
  261.    hdc = GetDC(ScreenHandle());
  262.    SelectObject(hdc,GetStockObject(SYSTEM_FONT));
  263.    GetTextMetrics(hdc,tm);
  264.    width = tm.AveCharWidth;
  265.    height = tm.Height + tm.ExternalLeading;
  266.    ReleaseDC(ScreenHandle(),hdc);
  267. }
  268.  
  269. GetWindowRect(hwnd,Rectangle)
  270. {
  271.    // set up blob to retrieve four integers
  272.    BLObSize(_rect,4 * 2/*integer size*/);
  273.    DynamicLink("USER","GETWINDOWRECT",SWORD16,PASCAL,hwnd,_rect);
  274.    Rectangle.left = BLObGet(_rect,0,SWORD16);
  275.    Rectangle.top = BLObGet(_rect,2,SWORD16);
  276.    Rectangle.right = BLObGet(_rect,4,SWORD16);
  277.    Rectangle.bottom = BLObGet(_rect,6,SWORD16);
  278. }
  279.  
  280. MoveWindow(hwnd,col,row,width,height,redraw)
  281. {
  282.    DynamicLink("USER","MOVEWINDOW",SWORD16,PASCAL,
  283.                hwnd,col,row,width,height,TRUE);
  284. }
  285.  
  286. GetClassName(hwnd,ClassName,MaxCount)
  287. {
  288.    return DynamicLink("USER","GETCLASSNAME",SWORD16,PASCAL,
  289.                       hwnd,ClassName,MaxCount);
  290. }
  291.  
  292. SetFocus(hwnd)
  293. {
  294.    return DynamicLink("USER","SETFOCUS",SWORD16,PASCAL,hwnd);
  295. }
  296.  
  297. GetWindowTextLength(hwnd)
  298. {
  299.    return DynamicLink("USER","GETWINDOWTEXTLENGTH",SWORD16,PASCAL,hwnd);
  300. }
  301.  
  302. GetEditText(hwnd,buf)   // make buf big enough
  303. {
  304.    _len = GetWindowTextLength(hwnd);
  305.    BLObSize(buf,_len+1);
  306.    if ( _len )
  307.       DynamicLink("USER","GETWINDOWTEXT",SWORD16,PASCAL,hwnd,buf,_len+1);
  308.    buf[_len] = '\0';
  309. }
  310.  
  311. IsWindowEnabled(WinHandle)
  312. {
  313.    return DynamicLink("USER","ISWINDOWENABLED",SWORD16,PASCAL,WinHandle);
  314. }
  315.  
  316. EnableWindow(WinHandle,EnableState)
  317. {
  318.    return DynamicLink("USER","ENABLEWINDOW",SWORD16,PASCAL,WinHandle,EnableState);
  319. }
  320.  
  321.