- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I read the previous thread and it was closed so I'm restarting it. I deliberately chose not to use ColorPicker cpommon dialog because rarely does the color I've picked look good on the full screen. So I created a small 'color picker' where I have a few radio buttons that I've selected and a fairly large picture object. Thinking that I would have a bigger area to see a color. Here is the basis of my code:
myRect%left = 104
myRect%top = 12
myRect%bottom = 96
myRect%right = 78
bret = MapDialogRect(hWnd, myRect)
hDC = GetDC(hWnd)
if (hDC == NULL) Then
bret = DeleteObject(myBrush)
Return
End If
iret = FillRect(hDC, myRect, myBrush) ! this should fill the picture control
where myBrush is created using the RGB values from the dialog radiobutton. I've included the full subroutine and callback as an attachment and a pdf of the dialog. Nothing really happens in the color dialog and I want to understand what I've done wrong to not get a color in the rectangular picture control.
Thanks,
Brooks
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If I understand what you have done sufficiently, the "picture control" has its own painting code, that will be called whenever the picture control receives WM_PAINT. That painting code will simply obliterate any drawing that you may have done in your dialog procedure.
Typically you would create your own custom "colour swatch" control (assuming there isn't already something that can do a similar job) - it doesn't have to be very complicated - just something that has some way of being told a current colour and then responds to WM_PAINT by filling its window with that colour; or you would subclass/reconfigure an existing control and modify it to do the job (perhaps you could use a static control and respond in the dialog to the WM_CTLCOLORSTATIC message); or you would customise the dialog template for the existing colour picker dialog to give it a bigger colour swatch area (you would have the same controls, just laid out differently).
(Looking at the type of control that the existing colour picker dialog uses for the colour swatches may be useful.)
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If I understand what you have done sufficiently, the "picture control" has its own painting code, that will be called whenever the picture control receives WM_PAINT. That painting code will simply obliterate any drawing that you may have done in your dialog procedure.
Typically you would create your own custom "colour swatch" control (assuming there isn't already something that can do a similar job) - it doesn't have to be very complicated - just something that has some way of being told a current colour and then responds to WM_PAINT by filling its window with that colour; or you would subclass/reconfigure an existing control and modify it to do the job (perhaps you could use a static control and respond in the dialog to the WM_CTLCOLORSTATIC message); or you would customise the dialog template for the existing colour picker dialog to give it a bigger colour swatch area (you would have the same controls, just laid out differently).
(Looking at the type of control that the existing colour picker dialog uses for the colour swatches may be useful.)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks, didn'y think of that. It seems trivky but I think I can pull it off.
Brooks
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
! Performs drawing of a color swatch. A color swatch is implemented ! as an owner-drawn button, and this subroutine is called in response ! to a WM_DRAWITEM message. The argument is the lParam of WM_DRAWITEM, ! which points to a DRAWITEMSTRUCT object. SUBROUTINE DrawColorSwatch (dis, color) IMPLICIT NONE INTEGER, INTENT(IN) :: color INTEGER :: rval TYPE(T_RECT) :: clientRect TYPE(T_DRAWITEMSTRUCT),INTENT(INOUT) :: dis rval = GetClientRect (dis%hwndItem, clientRect) CALL fill_rectangle (dis%hDc, color, clientRect) END SUBROUTINE DrawColorSwatch
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Paul,
Is this routine part of the dlg proc or part of winmainproc?
Brooks
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Here is the relevent code from the proc for the dialog (not the main Winproc). Interestingly, IVF does not allow passing lParam directly as an argument with the pointer assigned in the subroutine. The "color" value is an integer which has modular scope (so not defined here).
INTEGER FUNCTION BkgndDialogProc(hwnd, msg, wParam, lParam) RESULT(res) !DEC$ IF DEFINED(_X86_) !DEC$ ATTRIBUTES STDCALL, ALIAS : '_BkgndDialogProc@16' :: BkgndDialogProc !DEC$ ELSE !DEC$ ATTRIBUTES STDCALL, ALIAS : 'BkgndDialogProc' :: BkgndDialogProc !DEC$ ENDIF IMPLICIT NONE INTEGER(HANDLE), INTENT(IN) :: hwnd INTEGER(UINT), INTENT(IN) :: msg INTEGER(fWPARAM), INTENT(IN) :: wParam INTEGER(fLPARAM), INTENT(IN) :: lParam INTEGER :: rval INTEGER(HANDLE) :: hwndControl INTEGER :: controlId INTEGER :: code TYPE(T_DRAWITEMSTRUCT) :: dis POINTER(lParam, dis) res = DefaultDialogProc(hwnd, msg, wParam, lParam) SELECT CASE (msg) ! ... many other CASEs CASE (WM_DRAWITEM) controlId = wParam IF (controlId == IDC_BACKGROUND_COLOR) THEN CALL DrawColorSwatch (dis, color) res = 1 END IF END SELECT END FUNCTION BkgndDialogProc
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Paul, would you please elaborate on your comment regarding passing lparam? I didn't understand it.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Steve,
DrawColorSwatch() is realized as a (tiny) subroutine because the overall program uses this in multiple places. My initial code for DrawColorSwatch() received lParam as an (integer, intent:in) argument, exactly as received from Windows, and made the POINTER(lParam, dis) association in the subroutine, but IVF objected to that, whereas the method shown in my post, passing the WinAPI type associated in the calling routine, works fine. Don't know why, seemed a bit strange, but I stopped worrying when I got it to work.
Regards,
Paul
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Ah - the integer (Cray) pointer statement. A pointer can be a dummy argument - I just tried that. The pointee cannot be a dummy argument. Can you show me a small source that exhibits the problem?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Steve,
The commented code lines show how this routine was originally coded, where lParam becomes the locDIS argument; did not work.
! Performs drawing of a color swatch. A color swatch is implemented ! as an owner-drawn button, and this subroutine is called in response ! to a WM_DRAWITEM message. The argument is the lParam of WM_DRAWITEM, ! which points to a DRAWITEMSTRUCT object. !SUBROUTINE DrawColorSwatch (locDIS, color) SUBROUTINE DrawColorSwatch (dis, color) IMPLICIT NONE !INTEGER(fLPARAM), INTENT(IN) :: locDIS INTEGER, INTENT(IN) :: color INTEGER :: rval TYPE(T_RECT) :: clientRect TYPE(T_DRAWITEMSTRUCT),INTENT(INOUT) :: dis !POINTER(locDIS, dis) ! dummy assignment to fool the compiler's unused-variables checker !rval = locDIS rval = GetClientRect (dis%hwndItem, clientRect) CALL fill_rectangle (dis%hDc, color, clientRect) END SUBROUTINE DrawColorSwatch
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The commented out code compiles for me. What went wrong? I wonder if you had an extra (or missing) level of indirection when you passed lparam. Windows passes it in by value - you might have supplied it as the address of a data structure (seems like it here). If you didn't accept it by value but then just passed what you got by reference you'd have an extra indirection.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Yes, you're probably correct as to the extra level of indirection. My code always compiles ;), but does not always run as expected; in this case it crashed since Windows did not find a DIS at (address) locDIS. At any rate, I found an easy solution and moved on.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page