Announcement

Collapse

Forum Guidelines

This forum is for finished source code that is working properly. If you have questions about this or any other source code, please post it in one of the Discussion Forums, not here.
See more
See less

Spin control used for input for Chi-square test

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Spin control used for input for Chi-square test


    ' This program example demonstrates the SPIN CONTROL i.e. an UP-DOWN CONTROL
    ' in conjunction with a buddy window. The program analyzes the statistical
    ' significance of the difference between two proportions. The input is made
    ' using 4 spin controls.
    '
    ' The code skeleton was generated using EZGUI Freeware Dialog Designer
    ' by Christopher R. Boss. See web site at EZGUI.COM
    ' This ingenious freeware is highly recommended.
    '
    ' For clarity unused code has been removed. Normally this is not
    ' necessary.
    '
    ' Erik Christensen, Copenhagen, Denmark. ----- e.chr@email.dk"
    Code:
    #COMPILE EXE
    #REGISTER NONE
    #DIM ALL          '  This is helpful to prevent errors in coding
    
     %NOANIMATE    = 1
     %NOBUTTON     = 1
     %NOCOMBO      = 1
     %NODRAGLIST   = 1
     %NOHEADER     = 1
     %NOIMAGELIST  = 1
     %NOLIST       = 1
     %NOTRACKBAR   = 1
    
     %MAX_SPIN = 16960 ' absolute maximum spin control input value
     %MIN_SPIN = 0     ' minimum spin control input value for this program
    
    #INCLUDE "win32api.inc" ' Must come first before other include files !
    #INCLUDE "commctrl.inc" ' The Common Controls include file !
    
    ' *************************************************************
    '              Application Constants and Declares
    ' *************************************************************
    
    %IDD_FORM1_LABEL_ABSENT       = 100
    %IDD_FORM1_LABEL_PRESENT      = 105
    %IDD_FORM1_LABELB             = 110
    %IDD_FORM1_LABELA             = 115
    %IDD_FORM1_UPDOWN_A_PRES      = 120
    %IDD_FORM1_UPDOWN_A_ABS       = 125
    %IDD_FORM1_UPDOWN_B_PRES      = 130
    %IDD_FORM1_UPDOWN_B_ABS       = 135
    %IDD_FORM1_BUTTON_COMPARE     = 140
    %IDD_FORM1_DESCRIBE           = 145
    %IDD_FORM1_TEXT_A_PRES        = 150
    %IDD_FORM1_TEXT_A_ABS         = 155
    %IDD_FORM1_TEXT_B_PRES        = 160
    %IDD_FORM1_TEXT_B_ABS         = 165
    %IDD_FORM1_TEXT_RESULTS       = 170
    %IDD_FORM1_BUTTON_EXIT        = 175
    ' --------------------------------------------------
    DECLARE SUB ShowDialog_Form1(BYVAL hParent&)
    DECLARE CALLBACK FUNCTION Form1_DLGPROC
    
    DECLARE CALLBACK FUNCTION CBF_FORM1_BUTTON_COMPARE()
    DECLARE CALLBACK FUNCTION CBF_FORM1_BUTTON_EXIT()
    
    DECLARE FUNCTION PCHI2(BYVAL CHI2 AS DOUBLE, BYVAL F9 AS DOUBLE) AS DOUBLE
    
    GLOBAL hForm1&    ' Dialog handle
    GLOBAL RESULT$
    GLOBAL TT$
    GLOBAL AnNo%
    
    FUNCTION PBMAIN
        LOCAL Count&
        LOCAL CC1 AS INIT_COMMON_CONTROLSEX
        ' from the "commctrl.inc" file:
        ' TYPE INIT_COMMON_CONTROLSEX
        '   dwSize AS LONG
        '   dwICC  AS LONG
        ' END TYPE
        CC1.dwSize=SIZEOF(CC1)
        CC1.dwICC=%ICC_WIN95_CLASSES
    
        ' from the "commctrl.inc" file:
        '   DECLARE SUB InitCommonControlsEx LIB "COMCTL32.DLL" ALIAS _
        '   "InitCommonControlsEx" (icc AS INIT_COMMON_CONTROLSEX)
        '   The InitCommonControlsEx function call ensures that the
        '   necessary common control dynamic-link library (DLL) is loaded.
        InitCommonControlsEX CC1
        ShowDialog_Form1 0
        DO
            DIALOG DOEVENTS TO Count&
        LOOP UNTIL Count&=0
    END FUNCTION
    
    ' *************************************************************
    '                    Application Dialogs
    ' *************************************************************
    
    SUB ShowDialog_Form1(BYVAL hParent&)
        LOCAL Style&, ExStyle&, T$,UDstyle&,BWstyle&,DWstyle&
        ' hParent& = 0 if no parent Dialog
        Style& = %WS_POPUP OR %DS_MODALFRAME OR %WS_CAPTION OR %WS_MINIMIZEBOX OR %WS_SYSMENU OR %DS_CENTER
        ExStyle& = 0
        DIALOG NEW hParent&, "Comparison of 2 Proportions (or Percentages) Demonstrating the Spin Control", _
             0, 0,  308,  225, Style&, ExStyle& TO hForm1&
        CONTROL ADD LABEL, hForm1&,  %IDD_FORM1_LABEL_ABSENT,  "Characteristic absent", 22, 114, 66, 10
        CONTROL ADD LABEL, hForm1&,  %IDD_FORM1_LABEL_PRESENT,  "Characteristic present", 22, 96, 66, 10
        CONTROL ADD LABEL, hForm1&,  %IDD_FORM1_LABELB,  "Group 2", 168, 82, 60, 10
        CONTROL ADD LABEL, hForm1&,  %IDD_FORM1_LABELA,  "Group 1", 98, 82, 60, 10
    
        UDstyle& = %WS_CHILD OR %WS_VISIBLE OR %UDS_SETBUDDYINT OR %UDS_NOTHOUSANDS
             '%UDS_SETBUDDYINT Causes the up-down control to set the text of
             '                 the buddy window when the position changes.
             '                 The text consists of the position - formatted as
             '                 a decimal string.
             '%UDS_NOTHOUSANDS Prevents insertion of a thousands separator between
             '                 every three decimal digits.
    
             'from the "commctrl.inc" file:
             '$UPDOWN_CLASS = "msctls_updown32"
        CONTROL ADD "msctls_updown32",hForm1&,%IDD_FORM1_UPDOWN_A_PRES,"",128,94,10,12,UDstyle&
        CONTROL ADD "msctls_updown32",hForm1&,%IDD_FORM1_UPDOWN_A_ABS,"",128,112,10,12,UDstyle&
        CONTROL ADD "msctls_updown32",hForm1&,%IDD_FORM1_UPDOWN_B_PRES,"",198,94,10,12,UDstyle&
        CONTROL ADD "msctls_updown32",hForm1&,%IDD_FORM1_UPDOWN_B_ABS,"",198,112,10,12,UDstyle&
    
        CONTROL ADD "Button", hForm1&,%IDD_FORM1_BUTTON_COMPARE,"Compare", 34, 128, 174, 12, _
            %WS_CHILD OR %WS_VISIBLE OR %BS_PUSHBUTTON OR %WS_TABSTOP CALL CBF_FORM1_BUTTON_COMPARE
    
        T$="This program compares statistically two independent proportions using the "+ _
        "Chi-square test."+$CRLF+"      Example:"+$CRLF+"Group 1 has 110 females and 90 "+ _
        "males. The proportion of females is 110/(110+90) = 0.55 or 55%."+$CRLF+ _
        "Group 2 has 56 females and 68 males. The proportion of females is 56/(56+68) = "+ _
        "0.45 or 45%."+$CRLF+"      Is this difference random, or is it statistically "+ _
        "significant? This you can determine by calculating the P-value"+ _
        " (the probability that this difference can be explained by random factors alone). "+ _
        "If the P-value is small say less than 0.05 or 5%, "+ _
        "then the difference is said to be statistically significant."+$CRLF+ _
        "      This program calculates the difference between the proportions (with 95% "+ _
        "confidence limits) and the P-value."+ _
        " It also demonstrates the spin control i.e. an up-down control in conjunction with "+ _
        "a buddy window."+$CRLF+"      The test is approximate, especially for small groups. "+ _
        $CRLF+"      You can perform the test many times with different numbers. The latest "+ _
        "result will always be on the top "+ _
        "of the window and immediately visible. The previous results will still be present "+ _
        "in the window. You can scroll down to them at any time."+$CRLF+ _
        "      Erik Christensen, Copenhagen, Denmark.    e.chr@email.dk"
    
        DWstyle& = %WS_CHILD OR %WS_VISIBLE OR %ES_MULTILINE OR %WS_VSCROLL OR %ES_READONLY OR %ES_LEFT
        CONTROL ADD TEXTBOX, hForm1&,%IDD_FORM1_DESCRIBE,T$,2,0,306,80,DWstyle&,%WS_EX_CLIENTEDGE
    
        BWstyle& = %WS_CHILD OR %WS_VISIBLE OR %ES_MULTILINE OR %ES_RIGHT OR %ES_AUTOHSCROLL OR %WS_TABSTOP
        CONTROL ADD TEXTBOX, hForm1&,  %IDD_FORM1_TEXT_A_PRES,  "", 90, 94, 38, 12,BWstyle&,%WS_EX_CLIENTEDGE
        CONTROL ADD TEXTBOX, hForm1&,  %IDD_FORM1_TEXT_A_ABS,  "", 90, 112, 38, 12,BWstyle&,%WS_EX_CLIENTEDGE
        CONTROL ADD TEXTBOX, hForm1&,  %IDD_FORM1_TEXT_B_PRES,  "", 160, 94, 38, 12,BWstyle&,%WS_EX_CLIENTEDGE
        CONTROL ADD TEXTBOX, hForm1&,  %IDD_FORM1_TEXT_B_ABS,  "", 160, 112, 38, 12,BWstyle&,%WS_EX_CLIENTEDGE
    
        CONTROL SEND hForm1&, %IDD_FORM1_UPDOWN_A_PRES, %UDM_SETBUDDY, _
                     GetDlgItem(hForm1&, %IDD_FORM1_TEXT_A_PRES), 0&
        'The %UDM_SETBUDDY message sets the buddy window for an up-down control.
        'Thus the up-down control and its associated byddy edit window act
        'together as a unity. This is taken care of by Windows.
    
        CONTROL SEND hForm1&, %IDD_FORM1_UPDOWN_A_PRES, _
                     %UDM_SETRANGE, 0&, MAKLNG(%MAX_SPIN, %MIN_SPIN)
        'The %UDM_SETRANGE message sets the minimum and maximum
        'positions (range) for an up-down control.
        CONTROL SEND hForm1&, %IDD_FORM1_UPDOWN_A_ABS, %UDM_SETBUDDY, _
                     GetDlgItem(hForm1&, %IDD_FORM1_TEXT_A_ABS), 0&
        CONTROL SEND hForm1&, %IDD_FORM1_UPDOWN_A_ABS, _
                     %UDM_SETRANGE, 0&, MAKLNG(%MAX_SPIN, %MIN_SPIN)
    
        CONTROL SEND hForm1&, %IDD_FORM1_UPDOWN_B_PRES, %UDM_SETBUDDY, _
                     GetDlgItem(hForm1&, %IDD_FORM1_TEXT_B_PRES), 0&
        CONTROL SEND hForm1&, %IDD_FORM1_UPDOWN_B_PRES, _
                     %UDM_SETRANGE, 0&, MAKLNG(%MAX_SPIN, %MIN_SPIN)
    
        CONTROL SEND hForm1&, %IDD_FORM1_UPDOWN_B_ABS, %UDM_SETBUDDY, _
                     GetDlgItem(hForm1&, %IDD_FORM1_TEXT_B_ABS), 0&
        CONTROL SEND hForm1&, %IDD_FORM1_UPDOWN_B_ABS, _
                     %UDM_SETRANGE, 0&, MAKLNG(%MAX_SPIN, %MIN_SPIN)
    
        CONTROL ADD TEXTBOX, hForm1&,%IDD_FORM1_TEXT_RESULTS,"",2,144,306,80, _
            %WS_CHILD OR %WS_VISIBLE OR %ES_MULTILINE OR %ES_READONLY OR _
            %ES_LEFT OR %ES_AUTOVSCROLL OR %WS_VSCROLL, _
            %WS_EX_CLIENTEDGE
        CONTROL ADD "Button", hForm1&,%IDD_FORM1_BUTTON_EXIT,"Exit",238,128,44,12, _
            %WS_CHILD OR %WS_VISIBLE OR %BS_PUSHBUTTON OR %WS_TABSTOP _
            CALL CBF_FORM1_BUTTON_EXIT
        DIALOG SHOW MODELESS hForm1& , CALL Form1_DLGPROC
    END SUB
    
    ' *************************************************************
    '                             Dialog Callback Procedure
    '                             for Form Form1
    '                             uses Global Handle - hForm1&
    ' *************************************************************
    
    CALLBACK FUNCTION Form1_DLGPROC
      ' not used
    END FUNCTION
    
    CALLBACK FUNCTION CBF_FORM1_BUTTON_COMPARE
        LOCAL A$,B$,C$,D$
        LOCAL AA%,BB%,CC%,DD%
        IF CBCTLMSG=%BN_CLICKED THEN
           CONTROL GET TEXT hFORM1&, %IDD_FORM1_TEXT_A_PRES TO A$
           CONTROL GET TEXT hFORM1&, %IDD_FORM1_TEXT_A_ABS  TO B$
           CONTROL GET TEXT hFORM1&, %IDD_FORM1_TEXT_B_PRES TO C$
           CONTROL GET TEXT hFORM1&, %IDD_FORM1_TEXT_B_ABS  TO D$
           AA%=VAL(A$): BB%=VAL(B$): CC%=VAL(C$): DD%=VAL(D$)
    
           IF (AA%>0 AND DD%>0) OR (BB%>0 AND CC%>0) THEN
              RESULT$=""
    
              CALL CALCULATE(AA%,BB%,CC%,DD%,RESULT$)
    
              TT$=RESULT$+TT$
              CONTROL SET TEXT hForm1&,  %IDD_FORM1_TEXT_RESULTS,TT$
           ELSE
              MSGBOX "Too many cells are zero. Cannot perform calculation.", _
                    %MB_ICONHAND,"Problem:"
           END IF
        END IF
    END FUNCTION
    
    CALLBACK FUNCTION CBF_FORM1_BUTTON_EXIT
          DIALOG END hForm1&
    END FUNCTION
    ' ------------------------------------------------
    
    SUB CALCULATE(A%,B%,C%,D%,T$)
      ' For a reference to the method see standard statistical textbooks
      ' e.g. Armitage P & Berry G. Statistical Methods in Medical Research,
      ' Blackwell, Oxford, 1994.
    
      LOCAL TN1  AS SINGLE, _
            TN2  AS SINGLE, _
            TNN  AS SINGLE, _
            P1   AS SINGLE, _
            P2   AS SINGLE, _
            PS   AS SINGLE, _
            SED  AS SINGLE, _
            DIF  AS SINGLE, _
            AB   AS SINGLE, _
            AC   AS SINGLE, _
            DB   AS SINGLE, _
            DC   AS SINGLE, _
            CHI2 AS DOUBLE, _
            NS   AS SINGLE, _
            OS   AS SINGLE, _
            P    AS DOUBLE
    
      INCR AnNo
      TN1=A%+B%
      TN2=C%+D%
      TNN=TN1+TN2
    
      P1=A%/TN1
      P2=C%/TN2
    
      T$=T$+" Analysis number:"+STR$(AnNo)+$CRLF
      T$=T$ + " Group 1: Proportion with characteristic (P1):" _
         +STR$(A%)+" /"+STR$(TN1)+" ="+FORMAT$(P1*100,"###.##")+"%"+$CRLF
    
      T$=T$ + " Group 2: Proportion with characteristic (P2):" _
         +STR$(C%)+" /"+STR$(TN2)+" ="+FORMAT$(P2*100,"###.##")+"%"+$CRLF
    
      PS=(A%+C%)/(TN1+TN2)
    
      SED=SQR(PS*(1-PS)*(1/TN1+1/TN2))
      DIF=A%/TN1-C%/TN2
    
      T$=T$ + " Difference between proportions (P1 - P2) =" _
         +FORMAT$(DIF*100,"###.##")+"%"+$CRLF
    
      NS=DIF*100-1.96*SED*100
      IF NS<-100 THEN NS=-100
      OS=DIF*100+1.96*SED*100
      IF OS>100 THEN OS=100
    
      T$=T$ + " 95% Confidence interval of difference: ("+FORMAT$(NS,"###.##") _
         +" , "+FORMAT$(OS,"###.##")+")"+$CRLF
    
      AB=A%+B%
      AC=A%+C%
      DB=D%+B%
      DC=D%+C%
    
      TNN=AB+DC
    ' CHI2=TNN*(ABS(A%*D%-B%*C%)-TNN/2)^2/(AB*DC*AC*DB) ' with Yates's corrrection
      CHI2=TNN*(ABS(A%*D%-B%*C%))^2/(AB*DC*AC*DB)       ' without Yates's correction
      T$=T$+ " Chi-square ="+ FORMAT$(CHI2,"####.###")+"    P-value ="
      P=PCHI2(CHI2,1)
      T$=T$+FORMAT$(P,"##.######")+$CRLF '+$CRLF
      IF P<0.05 THEN
         T$=T$+" The difference is statistically significant."
      ELSE
         T$=T$+" The difference is not statistically significant and probably random."
      END IF
      T$=T$+$CRLF+$CRLF
    
    END SUB
    
    ' *************************************************************
    
    FUNCTION PCHI2(BYVAL X AS DOUBLE, BYVAL F AS DOUBLE) AS DOUBLE
    
    ' FUNCTION PCHI2 - CALCULATES THE P-VALUE FROM
    ' THE CHI-SQUARE VALUE AND THE DEGREES OF FREEDOM (BEING 1 IN THIS PROGRAM)
    ' The probability is calculated using series expansions 26.4.4 and 26.4.5
    ' in: Handbook of mathematical Functions. Editors: Abramowitz M & Stegun IA,
    ' Dover, New York, 1972. The function looks awful, but it does the job.
    
            LOCAL D#,E#,R#,G#,H#,SL#,S#,T#,P#,C#,SK#,Q#
            Q# = 1
            IF X>30 AND F=1 THEN Q=0: GOTO 4255 ' added to prevent overflow problems
            IF X = 0 OR F = 0 THEN GOTO 4255
            D# = F: E# = D# / 2: R# = F - INT(F / 2) * 2
            G# = 1
            IF R# > .3 THEN GOTO 4205
      4190  E# = E# - 1
            IF E# < 1.8 THEN GOTO 4225
            G# = G# * E#: GOTO 4190
      4205  G# = SQR(ATN(1) * 4) ' = PI
      4210  E# = E# - 1
            IF E# < .3 THEN GOTO 4225
            G# = G# * E#: GOTO 4210
      4225  H# = ((X / 2) ^ (D# / 2) * EXP(-X / 2)) / (X * G#)
            SL# = H# * 2 * X / D#: S# = 0: T# = 0: P# = 1
      4230  D# = D# + 2: P# = P# * X / D#: S# = S# + P#: C# = ABS(S# - T#)
            IF C# < .0000000001# THEN GOTO 4245
            T# = S#: GOTO 4230
      4245  SK# = (S# + 1) * SL#: Q# = 1 - SK#
            IF Q# < .0000000001# THEN Q# = .0000000001#
      4255  FUNCTION = Q#
    
    END FUNCTION

    [This message has been edited by Erik Christensen (edited June 30, 2005).]

  • #2
    One line needs to be changed :

    Code:
        BWstyle& = %WS_CHILD OR %WS_VISIBLE OR %ES_RIGHT OR %WS_TABSTOP
    You used the wrong styles for the text boxes and they don't respond
    to the updown controls in WIN95 !


    ------------------
    Chris Boss
    Computer Workshop
    Developer of "EZGUI"
    http://cwsof.com
    http://twitter.com/EZGUIProGuy

    Comment


    • #3
      Thank you for your comment.

      At the moment I still use Windows 95 but I will soon update.
      The style flags I use (for BWstyle&) work OK on my computer.

      The reason I have chosen those particular style flags is that
      I wanted the numbers to be right-aligned in the four buddy
      windows.

      The style you propose which includes %ES_RIGHT does
      not produce right alignment in my system but works otherwise OK.

      The PBDLL60 help file specifies that %ES_RIGHT only works in a
      multiline text box.

      Therefore I included %ES_MULTILINE in the style-specification
      and it did the job even though the buddy windows are in fact
      only one line high. The %ES_AUTOHSCROLL style is of course not
      necessary and could very well be deleted.

      Can you explain why the style flags I use work on my system,
      but not on yours? Is it a consequence of different versions of
      Windows?

      Erik


      ------------------

      Comment


      • #4
        This version includes calculation of odds-ratio with confidence limits. It does work with PBWin10.

        Best regards,

        Erik

        Code:
        #COMPILE EXE
        #REGISTER NONE
        #DIM ALL          '  This is helpful to prevent errors in coding
        
         %NOANIMATE    = 1
         %NOBUTTON     = 1
         %NOCOMBO      = 1
         %NODRAGLIST   = 1
         %NOHEADER     = 1
         %NOIMAGELIST  = 1
         %NOLIST       = 1
         %NOTRACKBAR   = 1
        
         %MAX_SPIN = 16960 ' absolute maximum spin control input value
         %MIN_SPIN = 0     ' minimum spin control input value for this program
        
        #INCLUDE "win32api.inc" ' Must come first before other include files !
        #INCLUDE "commctrl.inc" ' The Common Controls include file !
        
        ' *************************************************************
        '              Application Constants and Declares
        ' *************************************************************
        
        %IDD_FORM1_LABEL_ABSENT       = 100
        %IDD_FORM1_LABEL_PRESENT      = 105
        %IDD_FORM1_LABELB             = 110
        %IDD_FORM1_LABELA             = 115
        %IDD_FORM1_UPDOWN_A_PRES      = 120
        %IDD_FORM1_UPDOWN_A_ABS       = 125
        %IDD_FORM1_UPDOWN_B_PRES      = 130
        %IDD_FORM1_UPDOWN_B_ABS       = 135
        %IDD_FORM1_BUTTON_COMPARE     = 140
        %IDD_FORM1_DESCRIBE           = 145
        %IDD_FORM1_TEXT_A_PRES        = 150
        %IDD_FORM1_TEXT_A_ABS         = 155
        %IDD_FORM1_TEXT_B_PRES        = 160
        %IDD_FORM1_TEXT_B_ABS         = 165
        %IDD_FORM1_TEXT_RESULTS       = 170
        %IDD_FORM1_BUTTON_EXIT        = 175
        ' --------------------------------------------------
        DECLARE SUB ShowDialog_Form1(BYVAL hParent&)
        DECLARE CALLBACK FUNCTION Form1_DLGPROC
        
        DECLARE CALLBACK FUNCTION CBF_FORM1_BUTTON_COMPARE()
        DECLARE CALLBACK FUNCTION CBF_FORM1_BUTTON_EXIT()
        
        DECLARE FUNCTION PCHI2(BYVAL CHI2 AS DOUBLE, BYVAL F9 AS DOUBLE) AS DOUBLE
        
        GLOBAL hForm1&    ' Dialog handle
        GLOBAL RESULT$
        GLOBAL TT$
        GLOBAL AnNo%
        
        FUNCTION PBMAIN
            LOCAL Count&
            LOCAL CC1 AS INIT_COMMON_CONTROLSEX
            ' from the "commctrl.inc" file:
            ' TYPE INIT_COMMON_CONTROLSEX
            '   dwSize AS LONG
            '   dwICC  AS LONG
            ' END TYPE
            CC1.dwSize=SIZEOF(CC1)
            CC1.dwICC=%ICC_WIN95_CLASSES
        
            ' from the "commctrl.inc" file:
            '   DECLARE SUB InitCommonControlsEx LIB "COMCTL32.DLL" ALIAS _
            '   "InitCommonControlsEx" (icc AS INIT_COMMON_CONTROLSEX)
            '   The InitCommonControlsEx function call ensures that the
            '   necessary common control dynamic-link library (DLL) is loaded.
            InitCommonControlsEX CC1
            ShowDialog_Form1 0
            DO
                DIALOG DOEVENTS TO Count&
            LOOP UNTIL Count&=0
        END FUNCTION
        
        ' *************************************************************
        '                    Application Dialogs
        ' *************************************************************
        
        SUB ShowDialog_Form1(BYVAL hParent&)
            LOCAL Style&, ExStyle&, T$,UDstyle&,BWstyle&,DWstyle&
            ' hParent& = 0 if no parent Dialog
            Style& = %WS_POPUP OR %DS_MODALFRAME OR %WS_CAPTION OR %WS_MINIMIZEBOX OR %WS_SYSMENU OR %DS_CENTER
            ExStyle& = 0
            DIALOG NEW PIXELS, hParent&, "Comparison of 2 Proportions (or Percentages) Demonstrating the Spin Control", _
                 0, 0,  308*2,  225*2, Style&, ExStyle& TO hForm1&
            CONTROL ADD LABEL, hForm1&,  %IDD_FORM1_LABEL_ABSENT,  "Characteristic absent", 22*2, 114*2, 66*2, 10*2
            CONTROL ADD LABEL, hForm1&,  %IDD_FORM1_LABEL_PRESENT,  "Characteristic present", 22*2, 96*2, 66*2, 10*2
            CONTROL ADD LABEL, hForm1&,  %IDD_FORM1_LABELB,  "Group 2", 168*2, 82*2, 60*2, 10*2
            CONTROL ADD LABEL, hForm1&,  %IDD_FORM1_LABELA,  "Group 1", 98*2, 82*2, 60*2, 10*2
        
            UDstyle& = %WS_CHILD OR %WS_VISIBLE OR 
        S_SETBUDDYINT OR 
        S_NOTHOUSANDS
                 '
        S_SETBUDDYINT Causes the up-down control to set the text of
                 '                 the buddy window when the position changes.
                 '                 The text consists of the position - formatted as
                 '                 a decimal string.
                 '
        S_NOTHOUSANDS Prevents insertion of a thousands separator between
                 '                 every three decimal digits.
        
                 'from the "commctrl.inc" file:
                 '$UPDOWN_CLASS = "msctls_updown32"
            CONTROL ADD "msctls_updown32",hForm1&,%IDD_FORM1_UPDOWN_A_PRES,"",128*2,94*2,10*2,12*2,UDstyle&
            CONTROL ADD "msctls_updown32",hForm1&,%IDD_FORM1_UPDOWN_A_ABS,"",128*2,112*2,10*2,12*2,UDstyle&
            CONTROL ADD "msctls_updown32",hForm1&,%IDD_FORM1_UPDOWN_B_PRES,"",198*2,94*2,10*2,12*2,UDstyle&
            CONTROL ADD "msctls_updown32",hForm1&,%IDD_FORM1_UPDOWN_B_ABS,"",198*2,112*2,10*2,12*2,UDstyle&
        
            CONTROL ADD "Button", hForm1&,%IDD_FORM1_BUTTON_COMPARE,"Compare", 34*2, 128*2, 174*2, 12*2, _
                %WS_CHILD OR %WS_VISIBLE OR %BS_PUSHBUTTON OR %WS_TABSTOP CALL CBF_FORM1_BUTTON_COMPARE
        
            T$="This program compares statistically two independent proportions using the "+ _
            "Chi-square test."+$CRLF+"      Example:"+$CRLF+"Group 1 has 110 females and 90 "+ _
            "males. The proportion of females is 110/(110+90) = 0.55 or 55%."+$CRLF+ _
            "Group 2 has 56 females and 68 males. The proportion of females is 56/(56+68) = "+ _
            "0.45 or 45%."+$CRLF+"      Is this difference random, or is it statistically "+ _
            "significant? This you can determine by calculating the P-value"+ _
            " (the probability that this difference can be explained by random factors alone). "+ _
            "If the P-value is small say less than 0.05 or 5%, "+ _
            "then the difference is said to be statistically significant."+$CRLF+ _
            "      This program calculates the difference between the proportions (with 95% "+ _
            "confidence limits) and the P-value."+ _
            " It also demonstrates the spin control i.e. an up-down control in conjunction with "+ _
            "a buddy window."+$CRLF+"      The test is approximate, especially for small groups. "+ _
            $CRLF+"      You can perform the test many times with different numbers. The latest "+ _
            "result will always be on the top "+ _
            "of the window and immediately visible. The previous results will still be present "+ _
            "in the window. You can scroll down to them at any time."+$CRLF+ _
            "      Best regards   Erik Christensen "
        
            DWstyle& = %WS_CHILD OR %WS_VISIBLE OR %ES_MULTILINE OR %WS_VSCROLL OR %ES_READONLY OR %ES_LEFT
            CONTROL ADD TEXTBOX, hForm1&,%IDD_FORM1_DESCRIBE,T$,2*2,0*2,306*2,80*2,DWstyle&,%WS_EX_CLIENTEDGE
            CONTROL SET COLOR hForm1&,%IDD_FORM1_DESCRIBE, %BLACK, RGB(200, 255, 200)
            BWstyle& = %WS_CHILD OR %WS_VISIBLE OR %ES_MULTILINE OR %ES_RIGHT OR %ES_AUTOHSCROLL OR %WS_TABSTOP
            CONTROL ADD TEXTBOX, hForm1&,  %IDD_FORM1_TEXT_A_PRES,  "", 90*2, 94*2, 38*2, 12*2,BWstyle&,%WS_EX_CLIENTEDGE
            CONTROL ADD TEXTBOX, hForm1&,  %IDD_FORM1_TEXT_A_ABS,  "", 90*2, 112*2, 38*2, 12*2,BWstyle&,%WS_EX_CLIENTEDGE
            CONTROL ADD TEXTBOX, hForm1&,  %IDD_FORM1_TEXT_B_PRES,  "", 160*2, 94*2, 38*2, 12*2,BWstyle&,%WS_EX_CLIENTEDGE
            CONTROL ADD TEXTBOX, hForm1&,  %IDD_FORM1_TEXT_B_ABS,  "", 160*2, 112*2, 38*2, 12*2,BWstyle&,%WS_EX_CLIENTEDGE
        
            CONTROL SEND hForm1&, %IDD_FORM1_UPDOWN_A_PRES, 
        M_SETBUDDY, _
                         GetDlgItem(hForm1&, %IDD_FORM1_TEXT_A_PRES), 0&
            'The 
        M_SETBUDDY message sets the buddy window for an up-down control.
            'Thus the up-down control and its associated byddy edit window act
            'together as a unity. This is taken care of by Windows.
        
            CONTROL SEND hForm1&, %IDD_FORM1_UPDOWN_A_PRES, _
                         
        M_SETRANGE, 0&, MAKLNG(%MAX_SPIN, %MIN_SPIN)
            'The 
        M_SETRANGE message sets the minimum and maximum
            'positions (range) for an up-down control.
            CONTROL SEND hForm1&, %IDD_FORM1_UPDOWN_A_ABS, 
        M_SETBUDDY, _
                         GetDlgItem(hForm1&, %IDD_FORM1_TEXT_A_ABS), 0&
            CONTROL SEND hForm1&, %IDD_FORM1_UPDOWN_A_ABS, _
                         
        M_SETRANGE, 0&, MAKLNG(%MAX_SPIN, %MIN_SPIN)
        
            CONTROL SEND hForm1&, %IDD_FORM1_UPDOWN_B_PRES, 
        M_SETBUDDY, _
                         GetDlgItem(hForm1&, %IDD_FORM1_TEXT_B_PRES), 0&
            CONTROL SEND hForm1&, %IDD_FORM1_UPDOWN_B_PRES, _
                         
        M_SETRANGE, 0&, MAKLNG(%MAX_SPIN, %MIN_SPIN)
        
            CONTROL SEND hForm1&, %IDD_FORM1_UPDOWN_B_ABS, 
        M_SETBUDDY, _
                         GetDlgItem(hForm1&, %IDD_FORM1_TEXT_B_ABS), 0&
            CONTROL SEND hForm1&, %IDD_FORM1_UPDOWN_B_ABS, _
                         
        M_SETRANGE, 0&, MAKLNG(%MAX_SPIN, %MIN_SPIN)
        
            CONTROL ADD TEXTBOX, hForm1&,%IDD_FORM1_TEXT_RESULTS,"",2*2,144*2,306*2,80*2, _
                %WS_CHILD OR %WS_VISIBLE OR %ES_MULTILINE OR %ES_READONLY OR _
                %ES_LEFT OR %ES_AUTOVSCROLL OR %WS_VSCROLL, _
                %WS_EX_CLIENTEDGE
            CONTROL SET COLOR hForm1&,%IDD_FORM1_TEXT_RESULTS, %BLACK, RGB(255, 255, 160)
        
            CONTROL ADD "Button", hForm1&,%IDD_FORM1_BUTTON_EXIT,"Exit",282*2,128*2,24*2,12*2, _
                %WS_CHILD OR %WS_VISIBLE OR %BS_PUSHBUTTON OR %WS_TABSTOP _
                CALL CBF_FORM1_BUTTON_EXIT
            DIALOG SHOW MODELESS hForm1& , CALL Form1_DLGPROC
        END SUB
        
        ' *************************************************************
        '                             Dialog Callback Procedure
        '                             for Form Form1
        '                             uses Global Handle - hForm1&
        ' *************************************************************
        
        CALLBACK FUNCTION Form1_DLGPROC
          ' not used
        END FUNCTION
        
        CALLBACK FUNCTION CBF_FORM1_BUTTON_COMPARE
            LOCAL A$,B$,C$,D$
            LOCAL AA!,BB!,CC!,DDD!
            IF CBCTLMSG=%BN_CLICKED THEN
               CONTROL GET TEXT hFORM1&, %IDD_FORM1_TEXT_A_PRES TO A$
               CONTROL GET TEXT hFORM1&, %IDD_FORM1_TEXT_A_ABS  TO B$
               CONTROL GET TEXT hFORM1&, %IDD_FORM1_TEXT_B_PRES TO C$
               CONTROL GET TEXT hFORM1&, %IDD_FORM1_TEXT_B_ABS  TO D$
               AA!=VAL(A$): BB!=VAL(B$): CC!=VAL(C$): DDD!=VAL(D$)
        
               IF (AA!>0 AND DDD!>0) OR (BB!>0 AND CC!>0) THEN
                  RESULT$=""
                  IF AA!=0.0 OR BB!=0.0 OR CC!=0.0 OR DDD! = 0.0 THEN AA! = AA! + 0.5 : BB! = BB! + 0.5 : CC! = CC! + 0.5 : DDD! = DDD! + 0.5
                  CALL CALCULATE(AA!,BB!,CC!,DDD!,RESULT$)
        
                  TT$=RESULT$+TT$
                  CONTROL SET TEXT hForm1&,  %IDD_FORM1_TEXT_RESULTS,TT$
               ELSE
                  MSGBOX "Too many cells are zero. Cannot perform calculation.", _
                        %MB_ICONHAND,"Problem:"
               END IF
            END IF
        END FUNCTION
        
        CALLBACK FUNCTION CBF_FORM1_BUTTON_EXIT
              DIALOG END hForm1&
        END FUNCTION
        ' ------------------------------------------------
        
        SUB CALCULATE(A!,B!,C!,D!,T$)
          ' For a reference to the method see standard statistical textbooks
          ' e.g. Armitage P & Berry G. Statistical Methods in Medical Research,
          ' Blackwell, Oxford, 1994.
        
          LOCAL TN1  AS SINGLE, _
                TN2  AS SINGLE, _
                TNN  AS SINGLE, _
                P1   AS SINGLE, _
                P2   AS SINGLE, _
                PS   AS SINGLE, _
                SED  AS SINGLE, _
                DIF  AS SINGLE, _
                AB   AS SINGLE, _
                AC   AS SINGLE, _
                DDB  AS SINGLE, _
                DC   AS SINGLE, _
                CHI2 AS DOUBLE, _
                NS   AS SINGLE, _
                OS   AS SINGLE, _
                P    AS DOUBLE
        
          INCR AnNo
          TN1=A!+B!
          TN2=C!+D!
          TNN=TN1+TN2
        
          P1=A!/TN1
          P2=C!/TN2
        
          T$=T$+" Analysis number:"+STR$(AnNo)+$CRLF
          T$=T$ + " Group 1: Proportion with characteristic (P1):" _
             +STR$(A!)+" /"+STR$(TN1)+" = "+FORMAT$(P1*100,"###.000")+"%"+$CRLF
        
          T$=T$ + " Group 2: Proportion with characteristic (P2):" _
             +STR$(C!)+" /"+STR$(TN2)+" = "+FORMAT$(P2*100,"###.000")+"%"+$CRLF
        
          PS=(A!+C!)/(TN1+TN2)
        
          SED=SQR(PS*(1-PS)*(1/TN1+1/TN2))
          DIF=A!/TN1-C!/TN2
        
          T$=T$ + " Difference between proportions (P1 - P2) = " _
             +FORMAT$(DIF*100,"###.000")+"%"+$CRLF
        
          NS=DIF*100-1.96*SED*100
          IF NS<-100 THEN NS=-100
          OS=DIF*100+1.96*SED*100
          IF OS>100 THEN OS=100
        
          T$=T$ + " 95% Confidence interval of difference: ("+FORMAT$(NS,"###.000") _
             +" , "+FORMAT$(OS,"###.000")+")"+$CRLF
        
          AB=A!+B!
          AC=A!+C!
          DDB=D!+B!
          DC=D!+C!
        
          TNN=AB+DC
        ' CHI2=TNN*(ABS(A!*D!-B!*C!)-TNN/2)^2/(AB*DC*AC*DDB%) ' with Yates's corrrection
          CHI2=TNN*(ABS(A!*D!-B!*C!))^2/(AB*DC*AC*DDB)       ' without Yates's correction
          T$=T$+ " Chi-square = "+ FORMAT$(CHI2,"####.000")+"    P-value = "
          P=PCHI2(CHI2,1)
          T$=T$+FORMAT$(P,"##.000000")+$CRLF '+$CRLF
        
          ' neutral adjustment for a zero value in a cell. This allows calculation of the odds ratio in such cases
          IF A!=0.0 OR B!=0.0 OR C!=0.0 OR D! = 0.0 THEN A! = A! + 0.5 : B! = B! + 0.5 : C! = C! + 0.5 : D! = D! + 0.5
        
          LOCAL oddsratio AS DOUBLE, lnoddsratio AS DOUBLE, SElnoddsratio AS DOUBLE
          LOCAL upperCL AS DOUBLE, lowerCL AS DOUBLE
          oddsratio = A! * D! / B! / C! : lnoddsratio = LOG(oddsratio)
          SElnoddsratio = SQR((1.0/A! + 1.0/B! + 1/C! + 1/D!))
          upperCL = lnoddsratio + 1.96 * SElnoddsratio
          lowerCL = lnoddsratio - 1.96 * SElnoddsratio
          T$=T$+ " Odds-ratio = "+FORMAT$(oddsratio, "######.000")+$CRLF
          T$=T$+ " 95% Confidence interval of odds-ratio: ("+FORMAT$((EXP(lowerCL)), "#####.000") + _
              " , "+FORMAT$((EXP(upperCL)),"#####.000")+")" +$CRLF '+$CRLF
          IF P<0.05 THEN
             T$=T$+" The difference is statistically significant."
          ELSE
             T$=T$+" The difference is not statistically significant and probably random."
          END IF
          T$=T$+$CRLF+$CRLF
        END SUB
        
        ' *************************************************************
        
        FUNCTION PCHI2(BYVAL X AS DOUBLE, BYVAL F AS DOUBLE) AS DOUBLE
        
        ' FUNCTION PCHI2 - CALCULATES THE P-VALUE FROM
        ' THE CHI-SQUARE VALUE AND THE DEGREES OF FREEDOM (BEING 1 IN THIS PROGRAM)
        ' The probability is calculated using series expansions 26.4.4 and 26.4.5
        ' in: Handbook of mathematical Functions. Editors: Abramowitz M & Stegun IA,
        ' Dover, New York, 1972. The function does the job superbly.
        
                LOCAL D#,E#,R#,G#,H#,SL#,S#,T#,P#,C#,SK#,Q#
                Q# = 1
                IF X>30 AND F=1 THEN Q=0: GOTO 10 ' added to prevent overflow problems
                IF X = 0 OR F = 0 THEN GOTO 10
                D# = F: E# = D# / 2: R# = F - INT(F / 2) * 2
                G# = 1
                IF R# > .3 THEN GOTO 6
             5  E# = E# - 1
                IF E# < 1.8 THEN GOTO 8
                G# = G# * E#: GOTO 5
             6  G# = SQR(ATN(1) * 4) ' = PI
             7  E# = E# - 1
                IF E# < .3 THEN GOTO 8
                G# = G# * E#: GOTO 7
             8  H# = ((X / 2) ^ (D# / 2) * EXP(-X / 2)) / (X * G#)
                SL# = H# * 2 * X / D#: S# = 0: T# = 0: P# = 1
             9  D# = D# + 2: P# = P# * X / D#: S# = S# + P#: C# = ABS(S# - T#)
                IF C# < .0000000001# THEN GOTO 11
                T# = S#: GOTO 9
             11 SK# = (S# + 1) * SL#: Q# = 1 - SK#
                IF Q# < .0000000001# THEN Q# = .0000000001#
             10  FUNCTION = Q#
        
        END FUNCTION
        Attached Files
        Last edited by Erik Christensen; 27 Aug 2013, 05:31 AM.

        Comment


        • #5
          Originally posted by Erik Christensen View Post
          This version includes calculation of odds-ratio with confidence limits. It does work with PBWin10.

          Best regards,

          Erik

          Code:
          #COMPILE EXE
          #REGISTER NONE
          #DIM ALL          '  This is helpful to prevent errors in coding
          
           %NOANIMATE    = 1
           %NOBUTTON     = 1
           %NOCOMBO      = 1
           %NODRAGLIST   = 1
           %NOHEADER     = 1
           %NOIMAGELIST  = 1
           %NOLIST       = 1
           %NOTRACKBAR   = 1
          
           %MAX_SPIN = 16960 ' absolute maximum spin control input value
           %MIN_SPIN = 0     ' minimum spin control input value for this program
          
          #INCLUDE "win32api.inc" ' Must come first before other include files !
          #INCLUDE "commctrl.inc" ' The Common Controls include file !
          
          ' *************************************************************
          '              Application Constants and Declares
          ' *************************************************************
          
          %IDD_FORM1_LABEL_ABSENT       = 100
          %IDD_FORM1_LABEL_PRESENT      = 105
          %IDD_FORM1_LABELB             = 110
          %IDD_FORM1_LABELA             = 115
          %IDD_FORM1_UPDOWN_A_PRES      = 120
          %IDD_FORM1_UPDOWN_A_ABS       = 125
          %IDD_FORM1_UPDOWN_B_PRES      = 130
          %IDD_FORM1_UPDOWN_B_ABS       = 135
          %IDD_FORM1_BUTTON_COMPARE     = 140
          %IDD_FORM1_DESCRIBE           = 145
          %IDD_FORM1_TEXT_A_PRES        = 150
          %IDD_FORM1_TEXT_A_ABS         = 155
          %IDD_FORM1_TEXT_B_PRES        = 160
          %IDD_FORM1_TEXT_B_ABS         = 165
          %IDD_FORM1_TEXT_RESULTS       = 170
          %IDD_FORM1_BUTTON_EXIT        = 175
          ' --------------------------------------------------
          DECLARE SUB ShowDialog_Form1(BYVAL hParent&)
          DECLARE CALLBACK FUNCTION Form1_DLGPROC
          
          DECLARE CALLBACK FUNCTION CBF_FORM1_BUTTON_COMPARE()
          DECLARE CALLBACK FUNCTION CBF_FORM1_BUTTON_EXIT()
          
          DECLARE FUNCTION PCHI2(BYVAL CHI2 AS DOUBLE, BYVAL F9 AS DOUBLE) AS DOUBLE
          
          GLOBAL hForm1&    ' Dialog handle
          GLOBAL RESULT$
          GLOBAL TT$
          GLOBAL AnNo%
          
          FUNCTION PBMAIN
              LOCAL Count&
              LOCAL CC1 AS INIT_COMMON_CONTROLSEX
              ' from the "commctrl.inc" file:
              ' TYPE INIT_COMMON_CONTROLSEX
              '   dwSize AS LONG
              '   dwICC  AS LONG
              ' END TYPE
              CC1.dwSize=SIZEOF(CC1)
              CC1.dwICC=%ICC_WIN95_CLASSES
          
              ' from the "commctrl.inc" file:
              '   DECLARE SUB InitCommonControlsEx LIB "COMCTL32.DLL" ALIAS _
              '   "InitCommonControlsEx" (icc AS INIT_COMMON_CONTROLSEX)
              '   The InitCommonControlsEx function call ensures that the
              '   necessary common control dynamic-link library (DLL) is loaded.
              InitCommonControlsEX CC1
              ShowDialog_Form1 0
              DO
                  DIALOG DOEVENTS TO Count&
              LOOP UNTIL Count&=0
          END FUNCTION
          
          ' *************************************************************
          '                    Application Dialogs
          ' *************************************************************
          
          SUB ShowDialog_Form1(BYVAL hParent&)
              LOCAL Style&, ExStyle&, T$,UDstyle&,BWstyle&,DWstyle&
              ' hParent& = 0 if no parent Dialog
              Style& = %WS_POPUP OR %DS_MODALFRAME OR %WS_CAPTION OR %WS_MINIMIZEBOX OR %WS_SYSMENU OR %DS_CENTER
              ExStyle& = 0
              DIALOG NEW PIXELS, hParent&, "Comparison of 2 Proportions (or Percentages) Demonstrating the Spin Control", _
                   0, 0,  308*2,  225*2, Style&, ExStyle& TO hForm1&
              CONTROL ADD LABEL, hForm1&,  %IDD_FORM1_LABEL_ABSENT,  "Characteristic absent", 22*2, 114*2, 66*2, 10*2
              CONTROL ADD LABEL, hForm1&,  %IDD_FORM1_LABEL_PRESENT,  "Characteristic present", 22*2, 96*2, 66*2, 10*2
              CONTROL ADD LABEL, hForm1&,  %IDD_FORM1_LABELB,  "Group 2", 168*2, 82*2, 60*2, 10*2
              CONTROL ADD LABEL, hForm1&,  %IDD_FORM1_LABELA,  "Group 1", 98*2, 82*2, 60*2, 10*2
          
              UDstyle& = %WS_CHILD OR %WS_VISIBLE OR 
          S_SETBUDDYINT OR 
          S_NOTHOUSANDS
                   '
          S_SETBUDDYINT Causes the up-down control to set the text of
                   '                 the buddy window when the position changes.
                   '                 The text consists of the position - formatted as
                   '                 a decimal string.
                   '
          S_NOTHOUSANDS Prevents insertion of a thousands separator between
                   '                 every three decimal digits.
          
                   'from the "commctrl.inc" file:
                   '$UPDOWN_CLASS = "msctls_updown32"
              CONTROL ADD "msctls_updown32",hForm1&,%IDD_FORM1_UPDOWN_A_PRES,"",128*2,94*2,10*2,12*2,UDstyle&
              CONTROL ADD "msctls_updown32",hForm1&,%IDD_FORM1_UPDOWN_A_ABS,"",128*2,112*2,10*2,12*2,UDstyle&
              CONTROL ADD "msctls_updown32",hForm1&,%IDD_FORM1_UPDOWN_B_PRES,"",198*2,94*2,10*2,12*2,UDstyle&
              CONTROL ADD "msctls_updown32",hForm1&,%IDD_FORM1_UPDOWN_B_ABS,"",198*2,112*2,10*2,12*2,UDstyle&
          
              CONTROL ADD "Button", hForm1&,%IDD_FORM1_BUTTON_COMPARE,"Compare", 34*2, 128*2, 174*2, 12*2, _
                  %WS_CHILD OR %WS_VISIBLE OR %BS_PUSHBUTTON OR %WS_TABSTOP CALL CBF_FORM1_BUTTON_COMPARE
          
              T$="This program compares statistically two independent proportions using the "+ _
              "Chi-square test."+$CRLF+"      Example:"+$CRLF+"Group 1 has 110 females and 90 "+ _
              "males. The proportion of females is 110/(110+90) = 0.55 or 55%."+$CRLF+ _
              "Group 2 has 56 females and 68 males. The proportion of females is 56/(56+68) = "+ _
              "0.45 or 45%."+$CRLF+"      Is this difference random, or is it statistically "+ _
              "significant? This you can determine by calculating the P-value"+ _
              " (the probability that this difference can be explained by random factors alone). "+ _
              "If the P-value is small say less than 0.05 or 5%, "+ _
              "then the difference is said to be statistically significant."+$CRLF+ _
              "      This program calculates the difference between the proportions (with 95% "+ _
              "confidence limits) and the P-value."+ _
              " It also demonstrates the spin control i.e. an up-down control in conjunction with "+ _
              "a buddy window."+$CRLF+"      The test is approximate, especially for small groups. "+ _
              $CRLF+"      You can perform the test many times with different numbers. The latest "+ _
              "result will always be on the top "+ _
              "of the window and immediately visible. The previous results will still be present "+ _
              "in the window. You can scroll down to them at any time."+$CRLF+ _
              "      Best regards   Erik Christensen "
          
              DWstyle& = %WS_CHILD OR %WS_VISIBLE OR %ES_MULTILINE OR %WS_VSCROLL OR %ES_READONLY OR %ES_LEFT
              CONTROL ADD TEXTBOX, hForm1&,%IDD_FORM1_DESCRIBE,T$,2*2,0*2,306*2,80*2,DWstyle&,%WS_EX_CLIENTEDGE
              CONTROL SET COLOR hForm1&,%IDD_FORM1_DESCRIBE, %BLACK, RGB(200, 255, 200)
              BWstyle& = %WS_CHILD OR %WS_VISIBLE OR %ES_MULTILINE OR %ES_RIGHT OR %ES_AUTOHSCROLL OR %WS_TABSTOP
              CONTROL ADD TEXTBOX, hForm1&,  %IDD_FORM1_TEXT_A_PRES,  "", 90*2, 94*2, 38*2, 12*2,BWstyle&,%WS_EX_CLIENTEDGE
              CONTROL ADD TEXTBOX, hForm1&,  %IDD_FORM1_TEXT_A_ABS,  "", 90*2, 112*2, 38*2, 12*2,BWstyle&,%WS_EX_CLIENTEDGE
              CONTROL ADD TEXTBOX, hForm1&,  %IDD_FORM1_TEXT_B_PRES,  "", 160*2, 94*2, 38*2, 12*2,BWstyle&,%WS_EX_CLIENTEDGE
              CONTROL ADD TEXTBOX, hForm1&,  %IDD_FORM1_TEXT_B_ABS,  "", 160*2, 112*2, 38*2, 12*2,BWstyle&,%WS_EX_CLIENTEDGE
          
              CONTROL SEND hForm1&, %IDD_FORM1_UPDOWN_A_PRES, 
          M_SETBUDDY, _
                           GetDlgItem(hForm1&, %IDD_FORM1_TEXT_A_PRES), 0&
              'The 
          M_SETBUDDY message sets the buddy window for an up-down control.
              'Thus the up-down control and its associated byddy edit window act
              'together as a unity. This is taken care of by Windows.
          
              CONTROL SEND hForm1&, %IDD_FORM1_UPDOWN_A_PRES, _
                           
          M_SETRANGE, 0&, MAKLNG(%MAX_SPIN, %MIN_SPIN)
              'The 
          M_SETRANGE message sets the minimum and maximum
              'positions (range) for an up-down control.
              CONTROL SEND hForm1&, %IDD_FORM1_UPDOWN_A_ABS, 
          M_SETBUDDY, _
                           GetDlgItem(hForm1&, %IDD_FORM1_TEXT_A_ABS), 0&
              CONTROL SEND hForm1&, %IDD_FORM1_UPDOWN_A_ABS, _
                           
          M_SETRANGE, 0&, MAKLNG(%MAX_SPIN, %MIN_SPIN)
          
              CONTROL SEND hForm1&, %IDD_FORM1_UPDOWN_B_PRES, 
          M_SETBUDDY, _
                           GetDlgItem(hForm1&, %IDD_FORM1_TEXT_B_PRES), 0&
              CONTROL SEND hForm1&, %IDD_FORM1_UPDOWN_B_PRES, _
                           
          M_SETRANGE, 0&, MAKLNG(%MAX_SPIN, %MIN_SPIN)
          
              CONTROL SEND hForm1&, %IDD_FORM1_UPDOWN_B_ABS, 
          M_SETBUDDY, _
                           GetDlgItem(hForm1&, %IDD_FORM1_TEXT_B_ABS), 0&
              CONTROL SEND hForm1&, %IDD_FORM1_UPDOWN_B_ABS, _
                           
          M_SETRANGE, 0&, MAKLNG(%MAX_SPIN, %MIN_SPIN)
          
              CONTROL ADD TEXTBOX, hForm1&,%IDD_FORM1_TEXT_RESULTS,"",2*2,144*2,306*2,80*2, _
                  %WS_CHILD OR %WS_VISIBLE OR %ES_MULTILINE OR %ES_READONLY OR _
                  %ES_LEFT OR %ES_AUTOVSCROLL OR %WS_VSCROLL, _
                  %WS_EX_CLIENTEDGE
              CONTROL SET COLOR hForm1&,%IDD_FORM1_TEXT_RESULTS, %BLACK, RGB(255, 255, 160)
          
              CONTROL ADD "Button", hForm1&,%IDD_FORM1_BUTTON_EXIT,"Exit",282*2,128*2,24*2,12*2, _
                  %WS_CHILD OR %WS_VISIBLE OR %BS_PUSHBUTTON OR %WS_TABSTOP _
                  CALL CBF_FORM1_BUTTON_EXIT
              DIALOG SHOW MODELESS hForm1& , CALL Form1_DLGPROC
          END SUB
          
          ' *************************************************************
          '                             Dialog Callback Procedure
          '                             for Form Form1
          '                             uses Global Handle - hForm1&
          ' *************************************************************
          
          CALLBACK FUNCTION Form1_DLGPROC
            ' not used
          END FUNCTION
          
          CALLBACK FUNCTION CBF_FORM1_BUTTON_COMPARE
              LOCAL A$,B$,C$,D$
              LOCAL AA!,BB!,CC!,DDD!
              IF CBCTLMSG=%BN_CLICKED THEN
                 CONTROL GET TEXT hFORM1&, %IDD_FORM1_TEXT_A_PRES TO A$
                 CONTROL GET TEXT hFORM1&, %IDD_FORM1_TEXT_A_ABS  TO B$
                 CONTROL GET TEXT hFORM1&, %IDD_FORM1_TEXT_B_PRES TO C$
                 CONTROL GET TEXT hFORM1&, %IDD_FORM1_TEXT_B_ABS  TO D$
                 AA!=VAL(A$): BB!=VAL(B$): CC!=VAL(C$): DDD!=VAL(D$)
          
                 IF (AA!>0 AND DDD!>0) OR (BB!>0 AND CC!>0) THEN
                    RESULT$=""
                    IF AA!=0.0 OR BB!=0.0 OR CC!=0.0 OR DDD! = 0.0 THEN AA! = AA! + 0.5 : BB! = BB! + 0.5 : CC! = CC! + 0.5 : DDD! = DDD! + 0.5
                    CALL CALCULATE(AA!,BB!,CC!,DDD!,RESULT$)
          
                    TT$=RESULT$+TT$
                    CONTROL SET TEXT hForm1&,  %IDD_FORM1_TEXT_RESULTS,TT$
                 ELSE
                    MSGBOX "Too many cells are zero. Cannot perform calculation.", _
                          %MB_ICONHAND,"Problem:"
                 END IF
              END IF
          END FUNCTION
          
          CALLBACK FUNCTION CBF_FORM1_BUTTON_EXIT
                DIALOG END hForm1&
          END FUNCTION
          ' ------------------------------------------------
          
          SUB CALCULATE(A!,B!,C!,D!,T$)
            ' For a reference to the method see standard statistical textbooks
            ' e.g. Armitage P & Berry G. Statistical Methods in Medical Research,
            ' Blackwell, Oxford, 1994.
          
            LOCAL TN1  AS SINGLE, _
                  TN2  AS SINGLE, _
                  TNN  AS SINGLE, _
                  P1   AS SINGLE, _
                  P2   AS SINGLE, _
                  PS   AS SINGLE, _
                  SED  AS SINGLE, _
                  DIF  AS SINGLE, _
                  AB   AS SINGLE, _
                  AC   AS SINGLE, _
                  DDB  AS SINGLE, _
                  DC   AS SINGLE, _
                  CHI2 AS DOUBLE, _
                  NS   AS SINGLE, _
                  OS   AS SINGLE, _
                  P    AS DOUBLE
          
            INCR AnNo
            TN1=A!+B!
            TN2=C!+D!
            TNN=TN1+TN2
          
            P1=A!/TN1
            P2=C!/TN2
          
            T$=T$+" Analysis number:"+STR$(AnNo)+$CRLF
            T$=T$ + " Group 1: Proportion with characteristic (P1):" _
               +STR$(A!)+" /"+STR$(TN1)+" = "+FORMAT$(P1*100,"###.000")+"%"+$CRLF
          
            T$=T$ + " Group 2: Proportion with characteristic (P2):" _
               +STR$(C!)+" /"+STR$(TN2)+" = "+FORMAT$(P2*100,"###.000")+"%"+$CRLF
          
            PS=(A!+C!)/(TN1+TN2)
          
            SED=SQR(PS*(1-PS)*(1/TN1+1/TN2))
            DIF=A!/TN1-C!/TN2
          
            T$=T$ + " Difference between proportions (P1 - P2) = " _
               +FORMAT$(DIF*100,"###.000")+"%"+$CRLF
          
            NS=DIF*100-1.96*SED*100
            IF NS<-100 THEN NS=-100
            OS=DIF*100+1.96*SED*100
            IF OS>100 THEN OS=100
          
            T$=T$ + " 95% Confidence interval of difference: ("+FORMAT$(NS,"###.000") _
               +" , "+FORMAT$(OS,"###.000")+")"+$CRLF
          
            AB=A!+B!
            AC=A!+C!
            DDB=D!+B!
            DC=D!+C!
          
            TNN=AB+DC
          ' CHI2=TNN*(ABS(A!*D!-B!*C!)-TNN/2)^2/(AB*DC*AC*DDB%) ' with Yates's corrrection
            CHI2=TNN*(ABS(A!*D!-B!*C!))^2/(AB*DC*AC*DDB)       ' without Yates's correction
            T$=T$+ " Chi-square = "+ FORMAT$(CHI2,"####.000")+"    P-value = "
            P=PCHI2(CHI2,1)
            T$=T$+FORMAT$(P,"##.000000")+$CRLF '+$CRLF
          
            ' neutral adjustment for a zero value in a cell. This allows calculation of the odds ratio in such cases
            IF A!=0.0 OR B!=0.0 OR C!=0.0 OR D! = 0.0 THEN A! = A! + 0.5 : B! = B! + 0.5 : C! = C! + 0.5 : D! = D! + 0.5
          
            LOCAL oddsratio AS DOUBLE, lnoddsratio AS DOUBLE, SElnoddsratio AS DOUBLE
            LOCAL upperCL AS DOUBLE, lowerCL AS DOUBLE
            oddsratio = A! * D! / B! / C! : lnoddsratio = LOG(oddsratio)
            SElnoddsratio = SQR((1.0/A! + 1.0/B! + 1/C! + 1/D!))
            upperCL = lnoddsratio + 1.96 * SElnoddsratio
            lowerCL = lnoddsratio - 1.96 * SElnoddsratio
            T$=T$+ " Odds-ratio = "+FORMAT$(oddsratio, "######.000")+$CRLF
            T$=T$+ " 95% Confidence interval of odds-ratio: ("+FORMAT$((EXP(lowerCL)), "#####.000") + _
                " , "+FORMAT$((EXP(upperCL)),"#####.000")+")" +$CRLF '+$CRLF
            IF P<0.05 THEN
               T$=T$+" The difference is statistically significant."
            ELSE
               T$=T$+" The difference is not statistically significant and probably random."
            END IF
            T$=T$+$CRLF+$CRLF
          END SUB
          
          ' *************************************************************
          
          FUNCTION PCHI2(BYVAL X AS DOUBLE, BYVAL F AS DOUBLE) AS DOUBLE
          
          ' FUNCTION PCHI2 - CALCULATES THE P-VALUE FROM
          ' THE CHI-SQUARE VALUE AND THE DEGREES OF FREEDOM (BEING 1 IN THIS PROGRAM)
          ' The probability is calculated using series expansions 26.4.4 and 26.4.5
          ' in: Handbook of mathematical Functions. Editors: Abramowitz M & Stegun IA,
          ' Dover, New York, 1972. The function does the job superbly.
          
                  LOCAL D#,E#,R#,G#,H#,SL#,S#,T#,P#,C#,SK#,Q#
                  Q# = 1
                  IF X>30 AND F=1 THEN Q=0: GOTO 10 ' added to prevent overflow problems
                  IF X = 0 OR F = 0 THEN GOTO 10
                  D# = F: E# = D# / 2: R# = F - INT(F / 2) * 2
                  G# = 1
                  IF R# > .3 THEN GOTO 6
               5  E# = E# - 1
                  IF E# < 1.8 THEN GOTO 8
                  G# = G# * E#: GOTO 5
               6  G# = SQR(ATN(1) * 4) ' = PI
               7  E# = E# - 1
                  IF E# < .3 THEN GOTO 8
                  G# = G# * E#: GOTO 7
               8  H# = ((X / 2) ^ (D# / 2) * EXP(-X / 2)) / (X * G#)
                  SL# = H# * 2 * X / D#: S# = 0: T# = 0: P# = 1
               9  D# = D# + 2: P# = P# * X / D#: S# = S# + P#: C# = ABS(S# - T#)
                  IF C# < .0000000001# THEN GOTO 11
                  T# = S#: GOTO 9
               11 SK# = (S# + 1) * SL#: Q# = 1 - SK#
                  IF Q# < .0000000001# THEN Q# = .0000000001#
               10  FUNCTION = Q#
          
          END FUNCTION
          The program contains a lot of typos. I place an updated version for PBWin10
          Here is the updated code:

          Code:
          #COMPILE EXE
          #REGISTER NONE
          #DIM ALL          '  This is helpful to prevent errors in coding
          
           %NOANIMATE    = 1
           %NOBUTTON     = 1
           %NOCOMBO      = 1
           %NODRAGLIST   = 1
           %NOHEADER     = 1
           %NOIMAGELIST  = 1
           %NOLIST       = 1
           %NOTRACKBAR   = 1
          
           %MAX_SPIN = 16960 ' absolute maximum spin control input value
           %MIN_SPIN = 0     ' minimum spin control input value for this program
          
          #INCLUDE "win32api.inc" ' Must come first before other include files !
          #INCLUDE "commctrl.inc" ' The Common Controls include file !
          
          ' *************************************************************
          '              Application Constants and Declares
          ' *************************************************************
          
          %IDD_FORM1_LABEL_ABSENT       = 100
          %IDD_FORM1_LABEL_PRESENT      = 105
          %IDD_FORM1_LABELB             = 110
          %IDD_FORM1_LABELA             = 115
          %IDD_FORM1_UPDOWN_A_PRES      = 120
          %IDD_FORM1_UPDOWN_A_ABS       = 125
          %IDD_FORM1_UPDOWN_B_PRES      = 130
          %IDD_FORM1_UPDOWN_B_ABS       = 135
          %IDD_FORM1_BUTTON_COMPARE     = 140
          %IDD_FORM1_DESCRIBE           = 145
          %IDD_FORM1_TEXT_A_PRES        = 150
          %IDD_FORM1_TEXT_A_ABS         = 155
          %IDD_FORM1_TEXT_B_PRES        = 160
          %IDD_FORM1_TEXT_B_ABS         = 165
          %IDD_FORM1_TEXT_RESULTS       = 170
          %IDD_FORM1_BUTTON_EXIT        = 175
          ' --------------------------------------------------
          DECLARE SUB ShowDialog_Form1(BYVAL hParent&)
          DECLARE CALLBACK FUNCTION Form1_DLGPROC
          
          DECLARE CALLBACK FUNCTION CBF_FORM1_BUTTON_COMPARE()
          DECLARE CALLBACK FUNCTION CBF_FORM1_BUTTON_EXIT()
          
          DECLARE FUNCTION PCHI2(BYVAL CHI2 AS DOUBLE, BYVAL F9 AS DOUBLE) AS DOUBLE
          
          GLOBAL hForm1&    ' Dialog handle
          GLOBAL RESULT$
          GLOBAL TT$
          GLOBAL AnNo%
          
          FUNCTION PBMAIN
              LOCAL Count&
              LOCAL CC1 AS INIT_COMMON_CONTROLSEX
              ' from the "commctrl.inc" file:
              ' TYPE INIT_COMMON_CONTROLSEX
              '   dwSize AS LONG
              '   dwICC  AS LONG
              ' END TYPE
              CC1.dwSize=SIZEOF(CC1)
              CC1.dwICC=%ICC_WIN95_CLASSES
          
              ' from the "commctrl.inc" file:
              '   DECLARE SUB InitCommonControlsEx LIB "COMCTL32.DLL" ALIAS _
              '   "InitCommonControlsEx" (icc AS INIT_COMMON_CONTROLSEX)
              '   The InitCommonControlsEx function call ensures that the
              '   necessary common control dynamic-link library (DLL) is loaded.
              InitCommonControlsEX CC1
              ShowDialog_Form1 0
              DO
                  DIALOG DOEVENTS TO Count&
              LOOP UNTIL Count&=0
          END FUNCTION
          
          ' *************************************************************
          '                    Application Dialogs
          ' *************************************************************
          
          SUB ShowDialog_Form1(BYVAL hParent&)
              LOCAL Style&, ExStyle&, T$,UDstyle&,BWstyle&,DWstyle&
              ' hParent& = 0 if no parent Dialog
              Style& = %WS_POPUP OR %DS_MODALFRAME OR %WS_CAPTION OR %WS_MINIMIZEBOX OR %WS_SYSMENU OR %DS_CENTER
              ExStyle& = 0
              DIALOG NEW PIXELS, hParent&, "Comparison of 2 Proportions (or Percentages) Demonstrating the Spin Control", _
                   0, 0,  308*2,  225*2, Style&, ExStyle& TO hForm1&
              CONTROL ADD LABEL, hForm1&,  %IDD_FORM1_LABEL_ABSENT,  "Characteristic absent", 22*2, 114*2, 66*2, 10*2
              CONTROL ADD LABEL, hForm1&,  %IDD_FORM1_LABEL_PRESENT,  "Characteristic present", 22*2, 96*2, 66*2, 10*2
              CONTROL ADD LABEL, hForm1&,  %IDD_FORM1_LABELB,  "Group 2", 168*2, 82*2, 60*2, 10*2
              CONTROL ADD LABEL, hForm1&,  %IDD_FORM1_LABELA,  "Group 1", 98*2, 82*2, 60*2, 10*2
          
              UDstyle& = %WS_CHILD OR _ 
          					%WS_VISIBLE OR _ 
          					%UDS_SETBUDDYINT OR _ 
          					%UDS_NOTHOUSANDS
                   '
          			'S_SETBUDDYINT Causes the up-down control to set the text of
                   '                 the buddy window when the position changes.
                   '                 The text consists of the position - formatted as
                   '                 a decimal string.
                   '
          			'S_NOTHOUSANDS Prevents insertion of a thousands separator between
                   '                 every three decimal digits.
          
                   'from the "commctrl.inc" file:
                   '$UPDOWN_CLASS = "msctls_updown32"
              CONTROL ADD "msctls_updown32",hForm1&,%IDD_FORM1_UPDOWN_A_PRES,"",128*2,94*2,10*2,12*2,UDstyle&
              CONTROL ADD "msctls_updown32",hForm1&,%IDD_FORM1_UPDOWN_A_ABS,"",128*2,112*2,10*2,12*2,UDstyle&
              CONTROL ADD "msctls_updown32",hForm1&,%IDD_FORM1_UPDOWN_B_PRES,"",198*2,94*2,10*2,12*2,UDstyle&
              CONTROL ADD "msctls_updown32",hForm1&,%IDD_FORM1_UPDOWN_B_ABS,"",198*2,112*2,10*2,12*2,UDstyle&
          
              CONTROL ADD "Button", hForm1&,%IDD_FORM1_BUTTON_COMPARE,"Compare", 34*2, 128*2, 174*2, 12*2, _
                  %WS_CHILD OR %WS_VISIBLE OR %BS_PUSHBUTTON OR %WS_TABSTOP CALL CBF_FORM1_BUTTON_COMPARE
          
              T$="This program compares statistically two independent proportions using the "+ _
              "Chi-square test."+$CRLF+"      Example:"+$CRLF+"Group 1 has 110 females and 90 "+ _
              "males. The proportion of females is 110/(110+90) = 0.55 or 55%."+$CRLF+ _
              "Group 2 has 56 females and 68 males. The proportion of females is 56/(56+68) = "+ _
              "0.45 or 45%."+$CRLF+"      Is this difference random, or is it statistically "+ _
              "significant? This you can determine by calculating the P-value"+ _
              " (the probability that this difference can be explained by random factors alone). "+ _
              "If the P-value is small say less than 0.05 or 5%, "+ _
              "then the difference is said to be statistically significant."+$CRLF+ _
              "      This program calculates the difference between the proportions (with 95% "+ _
              "confidence limits) and the P-value."+ _
              " It also demonstrates the spin control i.e. an up-down control in conjunction with "+ _
              "a buddy window."+$CRLF+"      The test is approximate, especially for small groups. "+ _
              $CRLF+"      You can perform the test many times with different numbers. The latest "+ _
              "result will always be on the top "+ _
              "of the window and immediately visible. The previous results will still be present "+ _
              "in the window. You can scroll down to them at any time."+$CRLF+ _
              "      Best regards   Erik Christensen "
          
              DWstyle& = %WS_CHILD OR %WS_VISIBLE OR %ES_MULTILINE OR %WS_VSCROLL OR %ES_READONLY OR %ES_LEFT
              CONTROL ADD TEXTBOX, hForm1&,%IDD_FORM1_DESCRIBE,T$,2*2,0*2,306*2,80*2,DWstyle&,%WS_EX_CLIENTEDGE
              CONTROL SET COLOR hForm1&,%IDD_FORM1_DESCRIBE, %BLACK, RGB(200, 255, 200)
              BWstyle& = %WS_CHILD OR %WS_VISIBLE OR %ES_MULTILINE OR %ES_RIGHT OR %ES_AUTOHSCROLL OR %WS_TABSTOP
              CONTROL ADD TEXTBOX, hForm1&,  %IDD_FORM1_TEXT_A_PRES,  "", 90*2, 94*2, 38*2, 12*2,BWstyle&,%WS_EX_CLIENTEDGE
              CONTROL ADD TEXTBOX, hForm1&,  %IDD_FORM1_TEXT_A_ABS,  "", 90*2, 112*2, 38*2, 12*2,BWstyle&,%WS_EX_CLIENTEDGE
              CONTROL ADD TEXTBOX, hForm1&,  %IDD_FORM1_TEXT_B_PRES,  "", 160*2, 94*2, 38*2, 12*2,BWstyle&,%WS_EX_CLIENTEDGE
              CONTROL ADD TEXTBOX, hForm1&,  %IDD_FORM1_TEXT_B_ABS,  "", 160*2, 112*2, 38*2, 12*2,BWstyle&,%WS_EX_CLIENTEDGE
          
              CONTROL SEND hForm1&, %IDD_FORM1_UPDOWN_A_PRES, %UDM_SETBUDDY, GetDlgItem(hForm1&, %IDD_FORM1_TEXT_A_PRES), 0&
              'The M_SETBUDDY message sets the buddy window for an up-down control.
              'Thus the up-down control and its associated byddy edit window act
              'together as a unity. This is taken care of by Windows.
          
              CONTROL SEND hForm1&, %IDD_FORM1_UPDOWN_A_PRES, %UDM_SETRANGE, 0&, MAKLNG(%MAX_SPIN, %MIN_SPIN)
              'The M_SETRANGE message sets the minimum and maximum
              'positions (range) for an up-down control.
              CONTROL SEND hForm1&, %IDD_FORM1_UPDOWN_A_ABS,  %UDM_SETBUDDY, GetDlgItem(hForm1&, %IDD_FORM1_TEXT_A_ABS), 0&
              CONTROL SEND hForm1&, %IDD_FORM1_UPDOWN_A_ABS,  %UDM_SETRANGE, 0&, MAKLNG(%MAX_SPIN, %MIN_SPIN)
          
              CONTROL SEND hForm1&, %IDD_FORM1_UPDOWN_B_PRES, %UDM_SETBUDDY, GetDlgItem(hForm1&, %IDD_FORM1_TEXT_B_PRES), 0&
              CONTROL SEND hForm1&, %IDD_FORM1_UPDOWN_B_PRES, %UDM_SETRANGE, 0&, MAKLNG(%MAX_SPIN, %MIN_SPIN)
          
              CONTROL SEND hForm1&, %IDD_FORM1_UPDOWN_B_ABS,  %UDM_SETBUDDY, GetDlgItem(hForm1&, %IDD_FORM1_TEXT_B_ABS), 0&
              CONTROL SEND hForm1&, %IDD_FORM1_UPDOWN_B_ABS,  %UDM_SETRANGE, 0&, MAKLNG(%MAX_SPIN, %MIN_SPIN)
          
              CONTROL ADD TEXTBOX, hForm1&,%IDD_FORM1_TEXT_RESULTS,"",2*2,144*2,306*2,80*2, _
                  %WS_CHILD OR %WS_VISIBLE OR %ES_MULTILINE OR %ES_READONLY OR _
                  %ES_LEFT OR %ES_AUTOVSCROLL OR %WS_VSCROLL, _
                  %WS_EX_CLIENTEDGE
          
              CONTROL SET COLOR hForm1&,%IDD_FORM1_TEXT_RESULTS, %BLACK, RGB(255, 255, 160)
          
              CONTROL ADD "Button", hForm1&,%IDD_FORM1_BUTTON_EXIT,"Exit",282*2,128*2,24*2,12*2, _
                  %WS_CHILD OR %WS_VISIBLE OR %BS_PUSHBUTTON OR %WS_TABSTOP _
                  CALL CBF_FORM1_BUTTON_EXIT
              DIALOG SHOW MODELESS hForm1& , CALL Form1_DLGPROC
          END SUB
          
          ' *************************************************************
          '                             Dialog Callback Procedure
          '                             for Form Form1
          '                             uses Global Handle - hForm1&
          ' *************************************************************
          
          CALLBACK FUNCTION Form1_DLGPROC
            ' not used
          END FUNCTION
          
          CALLBACK FUNCTION CBF_FORM1_BUTTON_COMPARE
              LOCAL A$,B$,C$,D$
              LOCAL AA!,BB!,CC!,DDD!
              IF CBCTLMSG=%BN_CLICKED THEN
                 CONTROL GET TEXT hFORM1&, %IDD_FORM1_TEXT_A_PRES TO A$
                 CONTROL GET TEXT hFORM1&, %IDD_FORM1_TEXT_A_ABS  TO B$
                 CONTROL GET TEXT hFORM1&, %IDD_FORM1_TEXT_B_PRES TO C$
                 CONTROL GET TEXT hFORM1&, %IDD_FORM1_TEXT_B_ABS  TO D$
                 AA!=VAL(A$): BB!=VAL(B$): CC!=VAL(C$): DDD!=VAL(D$)
          
                 IF (AA!>0 AND DDD!>0) OR (BB!>0 AND CC!>0) THEN
                    RESULT$=""
                    IF AA!=0.0 OR BB!=0.0 OR CC!=0.0 OR DDD! = 0.0 THEN AA! = AA! + 0.5 : BB! = BB! + 0.5 : CC! = CC! + 0.5 : DDD! = DDD! + 0.5
                    CALL CALCULATE(AA!,BB!,CC!,DDD!,RESULT$)
          
                    TT$=RESULT$+TT$
                    CONTROL SET TEXT hForm1&,  %IDD_FORM1_TEXT_RESULTS,TT$
                 ELSE
                    MSGBOX "Too many cells are zero. Cannot perform calculation.", _
                          %MB_ICONHAND,"Problem:"
                 END IF
              END IF
          END FUNCTION
          
          CALLBACK FUNCTION CBF_FORM1_BUTTON_EXIT
                DIALOG END hForm1&
          END FUNCTION
          ' ------------------------------------------------
          
          SUB CALCULATE(A!,B!,C!,D!,T$)
            ' For a reference to the method see standard statistical textbooks
            ' e.g. Armitage P & Berry G. Statistical Methods in Medical Research,
            ' Blackwell, Oxford, 1994.
          
            LOCAL TN1  AS SINGLE, _
                  TN2  AS SINGLE, _
                  TNN  AS SINGLE, _
                  P1   AS SINGLE, _
                  P2   AS SINGLE, _
                  PS   AS SINGLE, _
                  SED  AS SINGLE, _
                  DIF  AS SINGLE, _
                  AB   AS SINGLE, _
                  AC   AS SINGLE, _
                  DDB  AS SINGLE, _
                  DC   AS SINGLE, _
                  CHI2 AS DOUBLE, _
                  NS   AS SINGLE, _
                  OS   AS SINGLE, _
                  P    AS DOUBLE
          
            INCR AnNo
            TN1=A!+B!
            TN2=C!+D!
            TNN=TN1+TN2
          
            P1=A!/TN1
            P2=C!/TN2
          
            T$=T$+" Analysis number:"+STR$(AnNo)+$CRLF
            T$=T$ + " Group 1: Proportion with characteristic (P1):" _
               +STR$(A!)+" /"+STR$(TN1)+" = "+FORMAT$(P1*100,"###.000")+"%"+$CRLF
          
            T$=T$ + " Group 2: Proportion with characteristic (P2):" _
               +STR$(C!)+" /"+STR$(TN2)+" = "+FORMAT$(P2*100,"###.000")+"%"+$CRLF
          
            PS=(A!+C!)/(TN1+TN2)
          
            SED=SQR(PS*(1-PS)*(1/TN1+1/TN2))
            DIF=A!/TN1-C!/TN2
          
            T$=T$ + " Difference between proportions (P1 - P2) = " _
               +FORMAT$(DIF*100,"###.000")+"%"+$CRLF
          
            NS=DIF*100-1.96*SED*100
            IF NS<-100 THEN NS=-100
            OS=DIF*100+1.96*SED*100
            IF OS>100 THEN OS=100
          
            T$=T$ + " 95% Confidence interval of difference: ("+FORMAT$(NS,"###.000") _
               +" , "+FORMAT$(OS,"###.000")+")"+$CRLF
          
            AB=A!+B!
            AC=A!+C!
            DDB=D!+B!
            DC=D!+C!
          
            TNN=AB+DC
          ' CHI2=TNN*(ABS(A!*D!-B!*C!)-TNN/2)^2/(AB*DC*AC*DDB%) ' with Yates's corrrection
            CHI2=TNN*(ABS(A!*D!-B!*C!))^2/(AB*DC*AC*DDB)       ' without Yates's correction
            T$=T$+ " Chi-square = "+ FORMAT$(CHI2,"####.000")+"    P-value = "
            P=PCHI2(CHI2,1)
            T$=T$+FORMAT$(P,"##.000000")+$CRLF '+$CRLF
          
            ' neutral adjustment for a zero value in a cell. This allows calculation of the odds ratio in such cases
            IF A!=0.0 OR B!=0.0 OR C!=0.0 OR D! = 0.0 THEN A! = A! + 0.5 : B! = B! + 0.5 : C! = C! + 0.5 : D! = D! + 0.5
          
            LOCAL oddsratio AS DOUBLE, lnoddsratio AS DOUBLE, SElnoddsratio AS DOUBLE
            LOCAL upperCL AS DOUBLE, lowerCL AS DOUBLE
            oddsratio = A! * D! / B! / C! : lnoddsratio = LOG(oddsratio)
            SElnoddsratio = SQR((1.0/A! + 1.0/B! + 1/C! + 1/D!))
            upperCL = lnoddsratio + 1.96 * SElnoddsratio
            lowerCL = lnoddsratio - 1.96 * SElnoddsratio
            T$=T$+ " Odds-ratio = "+FORMAT$(oddsratio, "######.000")+$CRLF
            T$=T$+ " 95% Confidence interval of odds-ratio: ("+FORMAT$((EXP(lowerCL)), "#####.000") + _
                " , "+FORMAT$((EXP(upperCL)),"#####.000")+")" +$CRLF '+$CRLF
            IF P<0.05 THEN
               T$=T$+" The difference is statistically significant."
            ELSE
               T$=T$+" The difference is not statistically significant and probably random."
            END IF
            T$=T$+$CRLF+$CRLF
          END SUB
          
          ' *************************************************************
          
          FUNCTION PCHI2(BYVAL X AS DOUBLE, BYVAL F AS DOUBLE) AS DOUBLE
          
          ' FUNCTION PCHI2 - CALCULATES THE P-VALUE FROM
          ' THE CHI-SQUARE VALUE AND THE DEGREES OF FREEDOM (BEING 1 IN THIS PROGRAM)
          ' The probability is calculated using series expansions 26.4.4 and 26.4.5
          ' in: Handbook of mathematical Functions. Editors: Abramowitz M & Stegun IA,
          ' Dover, New York, 1972. The function does the job superbly.
          
                  LOCAL D#,E#,R#,G#,H#,SL#,S#,T#,P#,C#,SK#,Q#
                  Q# = 1
                  IF X>30 AND F=1 THEN Q=0: GOTO 10 ' added to prevent overflow problems
                  IF X = 0 OR F = 0 THEN GOTO 10
                  D# = F: E# = D# / 2: R# = F - INT(F / 2) * 2
                  G# = 1
                  IF R# > .3 THEN GOTO 6
               5  E# = E# - 1
                  IF E# < 1.8 THEN GOTO 8
                  G# = G# * E#: GOTO 5
               6  G# = SQR(ATN(1) * 4) ' = PI
               7  E# = E# - 1
                  IF E# < .3 THEN GOTO 8
                  G# = G# * E#: GOTO 7
               8  H# = ((X / 2) ^ (D# / 2) * EXP(-X / 2)) / (X * G#)
                  SL# = H# * 2 * X / D#: S# = 0: T# = 0: P# = 1
               9  D# = D# + 2: P# = P# * X / D#: S# = S# + P#: C# = ABS(S# - T#)
                  IF C# < .0000000001# THEN GOTO 11
                  T# = S#: GOTO 9
               11 SK# = (S# + 1) * SL#: Q# = 1 - SK#
                  IF Q# < .0000000001# THEN Q# = .0000000001#
               10  FUNCTION = Q#
          
          END FUNCTION

          Comment

          Working...
          X