Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
Announcements
FPGA community forums and blogs on community.intel.com are migrating to the new Altera Community and are read-only. For urgent support needs during this transition, please visit the FPGA Design Resources page or contact an Altera Authorized Distributor.
29283 Discussions

Dialog box with a variable number of controls

dboggs
New Contributor I
4,920 Views

I am writing a Fortran Console application that uses a single dialog box. The box contains a variable number of checkbox controls; i.e. the program must add and remove checkboxes. Not having much experience with this--and not even sure it is possible--I am contemplating a brute force approach where my program directly edits the resource.rc file. An excerpt from this file (an example dialog that contains two checkbox controls) is

IDD_DIALOG1 DIALOG DISCARDABLE 0, 0, 362, 230
STYLE DS_MODALFRAME ! WS_POPUP ! WS_CAPTION ! WS_SYSMENU
CAPTION "Keyword list"
FONT 8, "Ms Sans Serif"
BEGIN
    CONTROL         "Check1",IDC_CHECK1,"Button",BS_AUTOCHECKBOX |
                    WS_TABSTOP,15,30,68,13
    CONTROL         "Check2",IDC_CHECK2,"Button",BS_AUTOCHECKBOX |
                    WS_TABSTOP,15,42,64,12
END

So, it appears that all my program has to do is manipulate the text in this Begin-End block, adding and removing lines. Right?

What worries me is that there is also an associated Resource.fd include file, and a Resource.h header file, which also contain similar information. Does my program also need to modify these? This would become much more burdensome. And, there is a statement in the "Digital Visual Fortran Programmer's Guide" (the only reference I have with info on this topic) warning that this may not work.

Or maybe there is a better way?

0 Kudos
29 Replies
dboggs
New Contributor I
1,277 Views

IanH and app4619:

Thanks for this info, BUT how do I "send a message" to LB_SETCOLUMNWIDTH within the IVF Fortran support, that is without going down the entire Windows API route? I tried DLGSET (dlg, IDC_LIST1, 50, LB_SETCOLUMNWIDTH) but got a compiler undefined function error. Probably because LB_SETCOLUMNWIDTH does not appear in the module IFLOGM. In other words it looks to me like IVF simply does not support this function.

I had hoped that the column width was a property that is set in the resource.rc file. But alas, I can find no example of that being done.

app4619: The way a multicolumn listbox works is fairly simple, even though it took me a fair amount of trial & error & reverse engineer to figure it out. The columns always display within the resource-defined size of the box. Setting a vertical scrollbar makes no sense but a horizontal scrollbar is logical. If the list is too long to fit in the listbox height, then it will snake (newspaper-like) into additional columns as needed. If the box is too narrow to display the additional columns, then a horizontal scrollbar appears. This is all exactly what I want, although it is messy to design for lack of control on the column width.

Luigi: Creating these at run time would be nice, but we already went through that problem (see earlier in this chain) and concluded that it is not possible.

I am still proceeding with a multicolumn listbox solution, despite its limitations. It certainly would be nice if Intel had included more support for this control. It is hobbled.

 

0 Kudos
andrew_4619
Honored Contributor III
1,277 Views

https://msdn.microsoft.com/en-us/library/windows/desktop/bb761338%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396

lres = SendDlgItemMessage(Dlg%hwnd, IDC_LIST_ORTH, LB_SETCOLUMNWIDTH, int(pixwidth_i_want,fwparam), 0_flparam )

Panic ye not, 'tis but one line of code.. decls as #16

0 Kudos
Paul_Curtis
Valued Contributor I
1,277 Views

"... It certainly would be nice if Intel had included more support for this control. It is hobbled."

A "multicolumn list box" is call a ListView, and is a very standard Windows control.  The fundamental impediment in this thread is that the OP wants all of the available Windows functionality, but is using an abstraction layer (Quickwin) which intentionally hides that functionality; those two things are simply not compatible.  The ultimate solution is to ditch the Quickwin and write a genuine first-principles Windows program, which can be done entirely from IVF.

You can the use the ListView freely in dialogs, and when you process the message loop for your own dialog you can then implement any sort of fanciness you want (different text foreground/background colors for line items with different attributes, associated images, etc.).  To whet your appetite for total control, consider the following set of F90 wrapper functions for ListView controls (and note specifically how easy it is to set the width of each added column):

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
! List view functions
!

!
! Adds a new column to a list view. The columnIndex is both the
! column position in the list view and the index of the associated
! subitem. The title is displayed for the column in the list view
! header, and the width is the column width in pixels.
!
SUBROUTINE ListViewAddColumn (hwnd, controlId, columnIndex, title, width, extraFormat)

    IMPLICIT NONE

    INTEGER(HANDLE), INTENT(IN)    :: hwnd
    INTEGER, INTENT(IN)            :: controlId
    INTEGER, INTENT(IN)            :: columnIndex
    CHARACTER(LEN=*), INTENT(IN)   :: title
    INTEGER, INTENT(IN)            :: width
	INTEGER, INTENT(IN),OPTIONAL   :: extraFormat

    TYPE(T_LV_COLUMN)              :: column
    INTEGER                        :: rval

    column%iSubItem = columnIndex
    column%pszText  = LOC(title)
    column%cx       = width
    column%mask     = IOR(LVCF_SUBITEM, LVCF_WIDTH)
    
	! extraFormat denotes text_is_centered or item_is_an_image
	IF (PRESENT(extraFormat)) THEN
		column%fmt = extraFormat
		column%mask = IOR(LVCF_FMT, column%mask)
		IF (extraFormat /= LVCFMT_IMAGE) column%mask = IOR(column%mask, LVCF_TEXT)
	
	!	if there is no extra argument, text content is assumed
	ELSE
		column%mask = IOR(column%mask, LVCF_TEXT)
	END IF
			
	rval = SendControlMessage(hwnd, controlId, LVM_INSERTCOLUMN, columnIndex, LOC(column))
    IF(rval == -1) THEN
        CALL ControlError("ListViewAddColumn", controlId, "failed")
    END IF

END SUBROUTINE ListViewAddColumn


!
! Returns the number of items in a list view.
!
INTEGER FUNCTION ListViewGetNumItems(hwnd, controlId)

    IMPLICIT NONE

    INTEGER(HANDLE), INTENT(IN)    :: hwnd
    INTEGER, INTENT(IN)            :: controlId

    INTEGER                        :: rval

    rval = SendControlMessage(hwnd, controlId, LVM_GETITEMCOUNT, 0, 0)
    IF(rval >= 0) THEN
        ListViewGetNumItems = rval
    ELSE
        CALL ControlError("ListViewGetNumItems", controlId, &
            "LVM_GETITEMCOUNT")
        ListViewGetNumItems = 0
    END IF

END FUNCTION ListViewGetNumItems


SUBROUTINE ListViewWideHighlight (hwnd, controlId)
    IMPLICIT NONE
    INTEGER(HANDLE), INTENT(IN)    :: hwnd
    INTEGER, INTENT(IN)            :: controlId

    INTEGER                        :: rval

    rval = SendControlMessage (hwnd, controlId,					&
							   LVM_SETEXTENDEDLISTVIEWSTYLE,	&
							   LVS_EX_FULLROWSELECT,			&
							   LVS_EX_FULLROWSELECT)
END SUBROUTINE ListViewWideHighlight


!	enable hover-detection for a listview control; hover information
!	is returned via LVN_HOTTRACK messages within WM_NOTIFY, and in this
!	program HandleListViewClick is used to resolve the selected item
SUBROUTINE ListViewHoverEnable (hwnd, controlId)
    IMPLICIT NONE
    INTEGER(HANDLE), INTENT(IN)    :: hwnd
    INTEGER, INTENT(IN)            :: controlId

    INTEGER                        :: rval

    rval = SendControlMessage (hwnd, controlId,					&
							   LVM_SETEXTENDEDLISTVIEWSTYLE,	&
							   LVS_EX_TRACKSELECT,				&
							   LVS_EX_TRACKSELECT)
END SUBROUTINE ListViewHoverEnable



!
! Removes all the items in a list view.
!
SUBROUTINE ListViewDeleteAllItems (hwnd, controlId)
    IMPLICIT NONE
    INTEGER(HANDLE), INTENT(IN)    :: hwnd
    INTEGER, INTENT(IN)            :: controlId

    INTEGER                        :: rval

    rval = SendControlMessage(hwnd, controlId, LVM_DELETEALLITEMS, 0, 0)
    IF (rval == 0) THEN
        CALL ControlError("ListViewDeleteAllItems", controlId, &
            "LVM_DELETEALLITEMS")
    END IF
    rval = SendControlMessage(hwnd, controlId, LVM_UPDATE, 0, 0)
    IF( rval == 0) THEN
        CALL ControlError("ListViewDeleteAllItems", controlId, &
            "LVM_UPDATE")
    END IF

END SUBROUTINE ListViewDeleteAllItems

!
! Adds an item to a list view. Returns the 1-based item index, 
! or -1 if the operation fails.
!
INTEGER FUNCTION ListViewAddItem (hwnd, controlId, name)

    IMPLICIT NONE

    INTEGER(HANDLE), INTENT(IN)    :: hwnd
    INTEGER, INTENT(IN)            :: controlId
    CHARACTER(LEN=*), INTENT(IN)   :: name

    INTEGER                        :: rval
    INTEGER                        :: nItems
    TYPE(T_LV_ITEM)                :: item
    CHARACTER(LEN=200)             :: buffer
    
    buffer = name
    CALL NullTerminateString (buffer)

    nItems        = ListViewGetNumItems (hwnd, controlId)
    item%mask     = LVIF_TEXT
    item%iItem    = nItems
    item%iSubitem = 0
    item%pszText  = LOC(buffer)
    
    rval = SendControlMessage(hwnd, controlId, LVM_INSERTITEM, 0, LOC(item))
    
    IF(rval /= -1) THEN
        ListViewAddItem = rval + 1
    ELSE
        CALL ControlError("ListViewAddItem", controlId, "LVM_INSERTITEM")
        ListViewAddItem = -1
    END IF

END FUNCTION ListViewAddItem


!
! Sets the text in a column for a single item in a list view control.
!                                             itemindex = row
SUBROUTINE ListViewSetColumn (hwnd, controlId, row, column, text, color)
    IMPLICIT NONE
    INTEGER(HANDLE), INTENT(IN)    :: hwnd
    INTEGER, INTENT(IN)            :: controlId
    INTEGER, INTENT(IN)            :: row
    INTEGER, INTENT(IN)            :: column
    CHARACTER(LEN=*), INTENT(IN)   :: text
	INTEGER, INTENT(IN), OPTIONAL  :: color

    INTEGER                        :: rval
    TYPE(T_LV_ITEM)                :: item
    CHARACTER(LEN=200)             :: buffer

	IF (PRESENT(color)) then
		rval = SendControlMessage (hwnd, controlId, LVM_SETTEXTCOLOR, 0, color)
	END IF

    buffer = text
    CALL NullTerminateString(buffer)

    item%mask     = LVIF_TEXT
    item%iItem    = row - 1		! row    is 1-based
    item%iSubitem = column		! column is 0-based
    item%pszText  = LOC(buffer)
    rval = SendControlMessage (hwnd, controlId, LVM_SETITEM, 0, LOC(item))
    IF (rval == -1) THEN
        CALL ControlError("ListViewSetColumn", controlId, "LVM_SETITEM")
    END IF

END SUBROUTINE ListViewSetColumn


SUBROUTINE ListViewSetImage (hwnd, controlId, row, column, image)
    IMPLICIT NONE
    INTEGER(HANDLE), INTENT(IN)    :: hwnd
    INTEGER, INTENT(IN)            :: controlId
    INTEGER, INTENT(IN)            :: row
    INTEGER, INTENT(IN)            :: column
    INTEGER, INTENT(IN)            :: image

    INTEGER                        :: rval
    TYPE(T_LV_ITEM)                :: item

    item%mask     = LVIF_IMAGE
    item%iItem    = row - 1		! row    is 1-based
    item%iSubitem = column		! column is 0-based
    item%iImage   = image
    rval = SendControlMessage (hwnd, controlId, LVM_SETITEM, 0, LOC(item))
    IF (rval == -1) THEN
        CALL ControlError("ListViewSetImage", controlId, "LVM_SETITEM")
    END IF
END SUBROUTINE ListViewSetImage


SUBROUTINE ListViewSetColumnHeader (hwnd, controlId, zb_colpos, text)
    IMPLICIT NONE
    INTEGER(HANDLE), INTENT(IN)    :: hwnd
    INTEGER, INTENT(IN)            :: controlId
    INTEGER, INTENT(IN)            :: zb_colpos		! zero-based column position
    CHARACTER(LEN=*), INTENT(IN)   :: text

    INTEGER                        :: rval
    TYPE(T_LVCOLUMN)               :: lvcolumn
    CHARACTER(LEN=100)             :: buffer

    buffer = text
    CALL NullTerminateString(buffer)

    lvcolumn%mask		= LVCF_TEXT
    lvcolumn%pszText	= LOC(buffer)
    lvcolumn%cchTextMax	= INDEX(buffer,CHAR(0))
	
	rval = SendControlMessage (hwnd, controlId, LVM_SETCOLUMN, zb_colpos, LOC(lvcolumn))
    IF (rval == -1) THEN
        CALL ControlError("ListViewSetColumnHeader", controlId, "LVM_SETCOLUMN")
    END IF
END SUBROUTINE ListViewSetColumnHeader


! 
! Sets the specified item in a list view control to selected. The
! index argument is 1-based.
!
SUBROUTINE ListViewSetSelectedIndex(hwnd, controlId, index)
    IMPLICIT NONE
    INTEGER(HANDLE), INTENT(IN)    :: hwnd
    INTEGER, INTENT(IN)            :: controlId
    INTEGER, INTENT(IN)            :: index
    INTEGER                        :: rval
    TYPE(T_LV_ITEM)                :: item
    
    item%iItem     = index - 1
    item%iSubitem  = 0
    item%mask      = LVIF_STATE
    item%state     = LVIS_SELECTED
    item%stateMask = LVIS_SELECTED
	 
    rval = SendControlMessage (hwnd, controlId, LVM_SETITEM, 0, LOC(item))
    IF (rval == -1) THEN
        CALL ControlError("ListViewSetSelectedIndex", controlId, &
            "LVM_SETITEM")
    END IF
END SUBROUTINE ListViewSetSelectedIndex


SUBROUTINE ListViewDeselect (hwnd, controlId)
    IMPLICIT NONE
    INTEGER(HANDLE), INTENT(IN)    :: hwnd
    INTEGER, INTENT(IN)            :: controlId
    INTEGER				           :: index
    INTEGER                        :: rval
    TYPE(T_LV_ITEM)                :: item
	index = ListViewGetSelectedIndex (hwnd, controlId)
	IF (index /= -1) THEN
		
		item%iItem     = index - 1
		item%iSubitem  = 0
		item%mask      = LVIF_STATE
		item%state     = 0
		item%stateMask = LVIS_SELECTED 
		
		rval = SendControlMessage (hwnd, controlId, LVM_SETITEM, 0, LOC(item))
		IF (rval == -1) THEN
			CALL ControlError("ListViewSetSelectedIndex", controlId, &
				"LVM_SETITEM")
        END IF
	END IF
END SUBROUTINE ListViewDeselect


!
! Returns the 1-based index of the currently selected item in a list view,
! or -1 if nothing is selected.
!
INTEGER FUNCTION ListViewGetSelectedIndex (hwnd, controlId, top) RESULT(index)

    IMPLICIT NONE

    INTEGER(HANDLE), INTENT(IN)    :: hwnd
    INTEGER, INTENT(IN)            :: controlId
	INTEGER, INTENT(INOUT),OPTIONAL:: top

    INTEGER                        :: rval
    INTEGER                        :: nItems
    TYPE(T_LV_ITEM)                :: lvitem
	TYPE(T_RECT)				   :: rect
    INTEGER                        :: i

    nItems = ListViewGetNumItems (hwnd, controlId)
    DO i = 0, nItems - 1
        lvitem%mask		 = LVIF_STATE
        lvitem%iItem	 = i
        lvitem%iSubitem	 = 0
        lvitem%stateMask = LVIS_SELECTED
        rval = SendControlMessage (hwnd, controlId, LVM_GETITEM, 0, LOC(lvitem))
        IF(rval /= 0) THEN
            IF (lvitem%state == LVIS_SELECTED) THEN
                IF (PRESENT(top)) THEN
					rval = SendControlMessage (hwnd, controlId, LVM_GETITEMRECT, i, LOC(rect))
					top = rect%top
				END IF
				index = i + 1
                RETURN
            END IF
        ELSE
            CALL ControlError("ListViewGetSelectedItem", controlId, "LVM_GETITEM")
        END IF
    END DO
    index = -1

END FUNCTION ListViewGetSelectedIndex


!
! Associates an integer value with a list view item, which can later
! be retrieved with ListViewGetItemData.
!
!  If the data is being stored for later use with NM_CUSTOMDRAW, such as
!  for setting a custom color for each element in the LV, this associated
!  integer vaue is returned within the NM_CUSTOMDRAW data structure as
!                nmlvcd%nmcd%lItemlParam

SUBROUTINE ListViewSetItemData (hwnd, controlId, index, valu)

    IMPLICIT NONE

    INTEGER(HANDLE), INTENT(IN)    :: hwnd
    INTEGER, INTENT(IN)            :: controlId
    INTEGER, INTENT(IN)            :: index
    INTEGER, INTENT(IN)            :: valu

    INTEGER                        :: rval
    TYPE(T_LV_ITEM)                :: item
    
    item%iItem    = index - 1
    item%iSubitem = 0
    item%mask     = LVIF_PARAM
    item%lparam   = valu
    rval = SendControlMessage(hwnd, controlId, LVM_SETITEM, 0, LOC(item))
    IF(rval == -1) THEN
        CALL ControlError("ListViewSetItemData", controlId, "LVM_SETITEM")
    END IF

END SUBROUTINE ListViewSetItemData


!
! Retrieves an integer data value associated with a list view item.
! If the operation fails, -1 is returned.
!
INTEGER FUNCTION ListViewGetItemData(hwnd, controlId, index) RESULT(valu)

    IMPLICIT NONE

    INTEGER(HANDLE), INTENT(IN)    :: hwnd
    INTEGER, INTENT(IN)            :: controlId
    INTEGER, INTENT(IN)            :: index

    INTEGER                        :: rval
    TYPE(T_LV_ITEM)                :: item
     
    item%iItem    = index - 1
    item%iSubitem = 0
    item%mask     = LVIF_PARAM
    rval = SendControlMessage(hwnd, controlId, LVM_GETITEM, 0, LOC(item))
    IF(rval /= -1) THEN
        valu = item%lparam
    ELSE
        CALL ControlError("ListViewGetItemData", controlId, "LVM_GETITEM")
        valu = -1
    END IF

END FUNCTION ListViewGetItemData


!
! Retrieves the integer data value associated with the currently
! selected item in the list view, or -1 if no item is currently
! selected.
!
INTEGER FUNCTION ListViewGetSelectedData(hwnd, controlId) RESULT(valu)

    IMPLICIT NONE

    INTEGER(HANDLE), INTENT(IN)    :: hwnd
    INTEGER, INTENT(IN)            :: controlId

    INTEGER                        :: sel

    sel = ListViewGetSelectedIndex(hwnd, controlId)
    IF(sel /= -1) THEN
        valu = ListViewGetItemData(hwnd, controlId, sel)
    ELSE
        valu = -1
    END IF

END FUNCTION ListViewGetSelectedData


! Call this function in response to the NM_CLICK message.  It
! causes a row to be selected if it is clicked on anywhere, not
! just in the first column.
!
SUBROUTINE HandleListViewClick (hwnd, controlId, got_one)
    IMPLICIT NONE
    INTEGER(HANDLE), INTENT(IN)    :: hwnd
    INTEGER, INTENT(IN)            :: controlId
	LOGICAL, INTENT(OUT),OPTIONAL  :: got_one

    INTEGER                        :: rval
    INTEGER                        :: nItems
    INTEGER(HANDLE)                :: hwndControl
    INTEGER                        :: i
    TYPE(T_RECT)                   :: rect
    TYPE(T_POINT)                  :: position
    TYPE(T_LV_ITEM)                :: item
	
	IF (PRESENT(got_one)) got_one = .FALSE.
	IF (n_enterwindows /= 0) RETURN

	! Probably should be GetMessagePos, but that's broken in DVF's
    ! headers, and this fills the bill OK.
    rval        = GetCursorPos (position)
    hwndControl = DialogGetControlWindow (hwnd, controlId)
    rval        = ScreenToClient (hwndControl, position)

    nItems = SendControlMessage (hwnd, controlId, LVM_GETITEMCOUNT, 0, 0)
    DO i = 0, nItems - 1
        rect%left = LVIR_BOUNDS 
        rval = SendControlMessage(hwnd, controlId, LVM_GETITEMRECT, i, LOC(rect))
        IF (PtInRect(rect, position)) THEN
            item%mask		= LVIF_STATE
            item%state		= IOR(LVIS_SELECTED, LVIS_FOCUSED)
            item%stateMask	= IOR(LVIS_SELECTED, LVIS_FOCUSED)
            rval = SendControlMessage (hwnd, controlId, LVM_SETITEMSTATE, i, LOC(item))
			IF (PRESENT(got_one)) got_one = .TRUE.
			EXIT
        END IF
    END DO

END SUBROUTINE HandleListViewClick


!	resolve a listview NM_HOVER message into the 1-based
!	index of the listview item which is being hovered over;
SUBROUTINE ListViewHover (hwnd, controlId, item)
    IMPLICIT NONE

    INTEGER(HANDLE), INTENT(IN)    :: hwnd
    INTEGER, INTENT(IN)            :: controlId
    INTEGER, INTENT(OUT)           :: item

    INTEGER                        :: rval, i
    INTEGER                        :: nItems
    INTEGER(HANDLE)                :: hwndControl
    TYPE(T_RECT)                   :: rect
    TYPE(T_POINT)                  :: position

	! Probably should be GetMessagePos, but that's broken in DVF's
    ! headers, and this fills the bill OK.
    rval        = GetCursorPos (position)
    hwndControl = DialogGetControlWindow (hwnd, controlId)
    rval        = ScreenToClient (hwndControl, position)

    nItems = SendControlMessage (hwnd, controlId, LVM_GETITEMCOUNT, 0, 0)
    DO i = 0, nItems - 1
        rect%left = LVIR_BOUNDS 
        rval = SendControlMessage(hwnd, controlId, LVM_GETITEMRECT, i, LOC(rect))
        IF (PtInRect(rect, position)) THEN
			item = i + 1
			RETURN
		END IF
    END DO
	item = 0

END SUBROUTINE ListViewHover


!   copied from IVF Forum post, not used at present
!FUNCTION ListView_GetCheckState(hwndLV, i) RESULT(state)  
!    USE IFWIN  
!    IMPLICIT NONE  
!    INTEGER(HANDLE), INTENT(IN) :: hwndLV  
!    INTEGER(UINT), INTENT(IN) :: i  
!    INTEGER(BOOL) :: state  
!    !----  
!    INTEGER(LRESULT) :: rc  
!    !****  
!    rc = SendMessage(hwndLV, LVM_GETITEMSTATE, KIND(i,UINT_PTR), LVIS_STATEIMAGEMASK)  
!    state = ISHFT(rc, -12) - 1  
!END FUNCTION ListView_GetCheckState  

 

0 Kudos
IanH
Honored Contributor III
1,277 Views

It is for the OP to clarify, but I think they are just using a core windows list box control (WC_LISTBOX or "List Box" in the VS resource editor) in multi-column mode - it only ever shows a simple list of text items (unless it is owner draw), but with the (rarely used) possibility of them being arranged in columns as well as vertically. 

A list view control (WC_LISTVIEW, or "List Control" in the VS dialog editor) is a different beast from the common controls library - it is along the lines (likely the exact same control) of the control used for the file list pane of the explorer shell window or file open dialog - items may be shown with icons, or in a multi-column details view (multiple fields of data per item), etc.

What's best depends on the OP's requirements (I happily use both), but if I wanted the user to do multiple selection of text only items, I would just give them a standard, boring, single column, vertically arranged, multiple selection list box.  If there was a need to indicate something simple other than just the item text and a state of selected or not selected, I would either alter the item text in some way (append a `*`), or make the listbox owner draw.and render the text of the item differently.  If there were requirements beyond that - then I would consider a list view control.

0 Kudos
andrew_4619
Honored Contributor III
1,277 Views

Thanks for the clarification of Paul's post Ian, the precise reference to the control names is helpful. I confess to being ignorant of "LIST CONTROL" .

I can see looking at Paui's sample there are a some instances in  my codes where LIST CONTROL could lead to an improved user interface so I will investigate that at some point, thanks for sharing the code snippets . This  is one of reason why I find this forum both interesting and useful - always new things to learn!

In relation to the OP, using "List Control" is not an option via IFLOGM. I myself  used to use the QuickWin interface but abandoned that approach quite some time ago use the Windows API directly. And I would fully agree  with Paul that it is not particularly difficult once you have got started and is much more feature rich. That said there is a significant learning hurdle in "getting started" which in many cases might not be worth the time and effort. QuickWin has its place  but you must accept its limitations if you use it,.

 

 

0 Kudos
GVautier
New Contributor III
1,277 Views

dboggs wrote:

I now realize I cannot alter the number of checkbox controls at runtime--I should have known.

 

It is possible to populate a dialog box with new controls during the initialization process. It is the way I use in order to be able to adapt dialog boxes to the context.

You must use createwindow(ex) API function with appropriate classname, style, parent, position and so on for each control you want to create.

At last, set the dialogbox size and position.

As far as I now the only thing needed is an empty dialogbox template in the ressource file.

 

 

 

 

0 Kudos
dboggs
New Contributor I
1,277 Views

gvautier: Thanks for this, I will check into it.

Paul and app49: Let's be careful on terminology. The right names for the controls are "list box" and "list view". They are two different things. It does not help to refer to something as a "List" control. I want a simple List box control with the multicolumn option enabled. I definitely do not want a single-column list, which would be very long, requiring the user to scroll excessively, and not be able to keep the entire list (or at least a large portion of it) in view. Typically, my list will vary from about 50 to 200 entries, which I plan to display in four or 5 columns of length 25. This will show up to 125 entries simultaneously, with horizontal scrolling by columns for any extra. This makes it easy for the user to ponder his selections. I described the behavior of a multicolumn list box in #22, and it is exactly what I want--or at least it would be if I could change the width of the columns. I further note that is very easy to do in a list box in Visual Basic (and I presume in other languages as well, without going the full Windows API route).

Paul: Thanks for the code sample, and I appreciate the power of a full windows project over standard Fortran with the quite limited extension calls provided by Intel. But, your demo is more than 500 lines long, and using the console project approach it only takes about 10 lines. I will definitely not go the full windows/API approach, even though that may indeed be best for a certain class of programmers, of which I am not a member. I hope you can appreciate that.

0 Kudos
andrew_4619
Honored Contributor III
1,277 Views

Actually I thought I was being careful with my terminology. "List Control" is what the Microsoft resource editor calls what is the referred to as  "List View" elsewhere. I think this confusion is not of may making!

Did the snip at post #23 not work BTW?

 

0 Kudos
dboggs
New Contributor I
1,277 Views


Well I stand corrected--sort of. I now see there are three terminologies in common use (as determine by the faultless internet): list box, list view, and list. I think these are three completely different things, although I can't be sure without studying the latter two more.

0 Kudos
Reply