- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I am working on a application that allows the user the select a patternfrom a list and ideally I would like the pattern to be previewed (drawn) in a box at the side so that it is obvious what is being selected. I understand that it is possible to direct OpenGL commands to a dialog box control but have not managed any success with this so far. Has anyone out there got an example that might help or could enlighten me with a brief description of the procedure? Most examples on the net are for C or C++ MFC applications.
What type of dialog control canI use (I assume Picture) to draw the picture?
Does the window have to be created using CreateWindow as CS_OWNDC or can a resource generated control be set up upon intialisation of the dialog?
I am using the dflogm module version of the dialog (with subclasses) to attempt this.
Any advice would be most welcome.
Thanks
Steve
What type of dialog control canI use (I assume Picture) to draw the picture?
Does the window have to be created using CreateWindow as CS_OWNDC or can a resource generated control be set up upon intialisation of the dialog?
I am using the dflogm module version of the dialog (with subclasses) to attempt this.
Any advice would be most welcome.
Thanks
Steve
Link Copied
7 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
My suggestion for the best way to offer a graphic-based selection menu would be to use owner-drawn buttons, which are developed in the resource editor in exactly the same manner as regular buttons, but given the owner-drawn attribute, and are also sized to fit whatever graphic they need to hold.
When your dialog proc loads, it sends the owner-drawn button a handle to the bitmap which is to be displayed on the button. In the sample code below, which occurs within the WM_INITDIALOG message response, IDC_STARTRUN is the id code for an owner-drawn button, and IDB_STARTRUN is a (pre-existing) bitmap which has been included as a project resource; hwnd is the handle to the dialog window:
(and when the dialog ends you will need to DeleteObject (hbitmap_start)).
While this is trivial to do, it does require that you provide your own explicit dialog proc which processes its message loop, ie you can't submerge or delegate this activity to Quickwin or a 3rd-party GUI tool or the like.
When your dialog proc loads, it sends the owner-drawn button a handle to the bitmap which is to be displayed on the button. In the sample code below, which occurs within the WM_INITDIALOG message response, IDC_STARTRUN is the id code for an owner-drawn button, and IDB_STARTRUN is a (pre-existing) bitmap which has been included as a project resource; hwnd is the handle to the dialog window:
[bash]hbitmap_start = LoadImageID (ghInstance, IDB_STARTRUN, IMAGE_BITMAP, 0,0,0) hwndControl = GetDlgItem (hwnd, IDC_STARTRUN) rval = SendMessage (hwndControl, BM_SETIMAGE, IMAGE_BITMAP, hbitmap_start) [/bash]
(and when the dialog ends you will need to DeleteObject (hbitmap_start)).
While this is trivial to do, it does require that you provide your own explicit dialog proc which processes its message loop, ie you can't submerge or delegate this activity to Quickwin or a 3rd-party GUI tool or the like.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I do not recommend to direct OpenGL commands to a dialog box control. Instead render OpenGL to a bitmap and display the bitmap in a dialog box control (e.g. by DLGSENDCTRLMESSAGE (dlg,controlid,STM_SETIMAGE,IMAGE_BITMAP,hbm). But rendering OpenGL to a bitmap is not easy. I did this in C but you can translate this to FORTRAN. Most functions are available in FORTRAN too. OpenGL functions beginning with gl or wgl begin in FORTRAN with fgl or fwgl. I don't know how to get the window handle hWnd if you are using DFLOGM but perhaps you find some hints in this forum. Hope this helps.
[cpp] HDC hMemDC,hdcrender,savhdcrender; HGLRC hglRC,savhglRC; HBITMAP hbm; BITMAPINFO *biinfo; hdcrender=GetDC(hWnd); // get DC of Dialog or Window // Create Bitmap hMemDC=CreateCompatibleDC(hdcrender); ZeroMemory(biinfo, sizeof(BITMAPINFO)); biinfo->bmiHeader.biSize=sizeof(BITMAPINFOHEADER); biinfo->bmiHeader.biWidth=*bmbrei; biinfo->bmiHeader.biHeight=*bmhoeh; biinfo->bmiHeader.biPlanes=1; biinfo->bmiHeader.biBitCount=24; biinfo->bmiHeader.biCompression=BI_RGB; biinfo->bmiHeader.biSizeImage=WIDTHBYTES((DWORD)biinfo->bmiHeader.biWidth * biinfo->bmiHeader.biBitCount) * biinfo->bmiHeader.biHeight; hbm=CreateDIBSection(hdcrender,biinfo,DIB_RGB_COLORS,&lpBits,NULL,(DWORD)0); SelectObject(hMemDC, hbm); // Set Pixelformat ZeroMemory(&pfd,sizeof(PIXELFORMATDESCRIPTOR)); pfd.nSize=sizeof(PIXELFORMATDESCRIPTOR); // size of this pfd pfd.nVersion=1; // version number pfd.dwFlags=PFD_DRAW_TO_BITMAP| PFD_SUPPORT_OPENGL; pfd.iPixelType=PFD_TYPE_RGBA; // RGBA type pfd.cColorBits=bitcount; // Bits per pixel pfd.cDepthBits=32; // Depth buffer pfd.iLayerType=PFD_MAIN_PLANE; // main layer if(!(nIndex=ChoosePixelFormat(hMemDC, &pfd))) bRet = FALSE; DescribePixelFormat(hMemDC,nIndex,sizeof(PIXELFORMATDESCRIPTOR),&pfd); bRet=SetPixelFormat(hMemDC,nIndex,&pfd); // Select Bitmap for drawing hglRC=wglCreateContext(hMemDC); wglMakeCurrent(hMemDC, hglRC); savhglRC=wglGetCurrentContext(); savhdcrender=wglGetCurrentDC(); // OpenGL Rendering glViewport(0,0,biinfo->bmiHeader.biWidth,biinfo->bmiHeader.biHeight) ... // wglMakeCurrent(savhdcrender,savhglRC); wglDeleteContext(hglRC); DeleteDC(hMemDC); ReleaseDC(*hWnd,hdcrender); [/cpp]
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
It is not clear whether you want to copy a pre-existing bitmap pattern into a window on your dialog or whether you need to execute drawing commands to create the pattern that you want to disply. WHich is it?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks for everyone's suggestions:
I need to actually draw the picture on the fly. I already use predefined bitmaps on buttons elsewhere in the programbuton thisoccaision I need to be able to draw whatever pattern the user has previously set up, and there could be many. The patterns consist ofa grid of lines boundaed by straight edges. At the moment the user can use a list box with descriptive text but this is notthat user friendly as "a picture can paint a thousand words" so they say.
The idea of creating a bitmap using Opengl and then Loading it has been considered but I reckoned it would be it bit clunky and slow. I might try it if I can't find a better way.
I know drawing can be done on dialog boxes as the OpenGLView utility (you get with OpenGL SuperBible - S Wright)shows a rendered image which changes as the user selects different pixel formats from those available on their graphics card. These images are also animated although I don't need to go to that degree of complexity.
I need to actually draw the picture on the fly. I already use predefined bitmaps on buttons elsewhere in the programbuton thisoccaision I need to be able to draw whatever pattern the user has previously set up, and there could be many. The patterns consist ofa grid of lines boundaed by straight edges. At the moment the user can use a list box with descriptive text but this is notthat user friendly as "a picture can paint a thousand words" so they say.
The idea of creating a bitmap using Opengl and then Loading it has been considered but I reckoned it would be it bit clunky and slow. I might try it if I can't find a better way.
I know drawing can be done on dialog boxes as the OpenGLView utility (you get with OpenGL SuperBible - S Wright)shows a rendered image which changes as the user selects different pixel formats from those available on their graphics card. These images are also animated although I don't need to go to that degree of complexity.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You do not have to use OpenGL to draw toa window. You could use functions such as
MSFWIN$Rectangle(Hdc,.., MSFWin$LineTo(hDC..., MoveToEx(hDc,.. to draw, and the usual Windows API functions to create pens, brushes, etc. (the odd names are because the Windows API function names have been taken over by Quickwin, and the API functions renamed in order to distinguish them from the QUickWIn versions).
To create an Ownerdraw window, add a static text window to your resource file using the resource editor. Then close the resource file, then open it as a text file and then edit the line defining the text box control to add the SS_OWNERDRAW style to it, like the CONTROL line in the resource file below (this supposes that the OwnerDraw style is not available from the properties tabs - if it is, then just select Ownerdraw style and ignore the editing instructions):
BEGIN
DEFPUSHBUTTON "Exit",IDOK,7,272,68,40,BS_MULTILINE
PUSHBUTTON "Scale Graphs DOWN",IDC_SCALEDOWN,7,63,68,40,
BS_MULTILINE
PUSHBUTTON "Scale Graphs UP",IDC_SCALEUP,7,13,68,40,BS_MULTILINE
PUSHBUTTON "Original Scale",IDC_SCALEORIGINAL,7,113,68,40,
BS_MULTILINE
CONTROL "",IDC_OWNER,"Static",SS_OWNERDRAW | SS_SUNKEN,77,12,314,
275
END
Just close and save your edit and reopen the file as 'resource' and your text box is now an OwnerDraw control.
To use the control, you have to subclass your dialog (see SetWindowLong API function), add your own dialog procedure to intercept the windows messages sent to the dialog box and to then process the WM_DRAWITEM message that windows issues when the control and everything in it has to be redrawn. Just add your drawing commands and pass the message on. The procedure must also pass all other unprocessed messages on to the default dialog procedure for processing.
You can find an article on Subclassing here;
http://software.intel.com/en-us/articles/how-to-customize-dialog-box-colors-using-subclassing/
MSFWIN$Rectangle(Hdc,.., MSFWin$LineTo(hDC..., MoveToEx(hDc,.. to draw, and the usual Windows API functions to create pens, brushes, etc. (the odd names are because the Windows API function names have been taken over by Quickwin, and the API functions renamed in order to distinguish them from the QUickWIn versions).
To create an Ownerdraw window, add a static text window to your resource file using the resource editor. Then close the resource file, then open it as a text file and then edit the line defining the text box control to add the SS_OWNERDRAW style to it, like the CONTROL line in the resource file below (this supposes that the OwnerDraw style is not available from the properties tabs - if it is, then just select Ownerdraw style and ignore the editing instructions):
BEGIN
DEFPUSHBUTTON "Exit",IDOK,7,272,68,40,BS_MULTILINE
PUSHBUTTON "Scale Graphs DOWN",IDC_SCALEDOWN,7,63,68,40,
BS_MULTILINE
PUSHBUTTON "Scale Graphs UP",IDC_SCALEUP,7,13,68,40,BS_MULTILINE
PUSHBUTTON "Original Scale",IDC_SCALEORIGINAL,7,113,68,40,
BS_MULTILINE
CONTROL "",IDC_OWNER,"Static",SS_OWNERDRAW | SS_SUNKEN,77,12,314,
275
END
Just close and save your edit and reopen the file as 'resource' and your text box is now an OwnerDraw control.
To use the control, you have to subclass your dialog (see SetWindowLong API function), add your own dialog procedure to intercept the windows messages sent to the dialog box and to then process the WM_DRAWITEM message that windows issues when the control and everything in it has to be redrawn. Just add your drawing commands and pass the message on. The procedure must also pass all other unprocessed messages on to the default dialog procedure for processing.
You can find an article on Subclassing here;
http://software.intel.com/en-us/articles/how-to-customize-dialog-box-colors-using-subclassing/
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I think you want to do something like what is shown in this image (ogl1.jpg):

The drop down-control is an ownerdrawn combobox. The bigger picture is a Picture-Control. Both are OpenGL scenes rendered to bitmaps. The sliders beside the OpenGL Image rotate the scene. No speed problem. (But you are right, it's a little bit clunky)
First I tried to render directly to the picture control but I failed because you can only speed it up if you use hardware acceleration. But depending on hardware and drivers sometimes it works and sometimes not, so I switched to bitmaps.
As far as I know you have to use a pixelformat including PFD_SUPPORT_GDI to render to dialog boxes which switches off hardware acceleration. And in this case I discover that rendering to bitmaps is often faster.
Perhaps your utility OpenGLView makes it more easy.

The drop down-control is an ownerdrawn combobox. The bigger picture is a Picture-Control. Both are OpenGL scenes rendered to bitmaps. The sliders beside the OpenGL Image rotate the scene. No speed problem. (But you are right, it's a little bit clunky)
First I tried to render directly to the picture control but I failed because you can only speed it up if you use hardware acceleration. But depending on hardware and drivers sometimes it works and sometimes not, so I switched to bitmaps.
As far as I know you have to use a pixelformat including PFD_SUPPORT_GDI to render to dialog boxes which switches off hardware acceleration. And in this case I discover that rendering to bitmaps is often faster.
Perhaps your utility OpenGLView makes it more easy.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear rwg:
Depending on your code, after rendering to hMemDC, why don't need to use bitblt to copy image on the screen?
// OpenGL Rendering |
38 |
glViewport(0,0,biinfo->bmiHeader.biWidth,biinfo->bmiHeader.biHeight) |
39 |
... |
40 |
// |
41 |
wglMakeCurrent(savhdcrender,savhglRC); |
42 |
wglDeleteContext(hglRC); |
43 |
DeleteDC(hMemDC); |
44 |
ReleaseDC(*hWnd,hdcrender); |

Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page