home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1994 #1 / monster.zip / monster / PROG_C / CENVIW9.ZIP / WHORYOU.CMM < prev    next >
Text File  |  1994-03-08  |  13KB  |  323 lines

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