MFC DockablePane not floating or hiding - mfc-feature-pack

Is there any way to make a MFC DockablePane (from the new Feature Pack) that is docked in a window not able to float or to hide (and even disable the context menu that allows the user to select the states - dockable, float, hide etc.)
What I basically want is to have 3 panes on a window that can change their horizontal dimensions, but not their position inside the window. Any suggestion?

The solution is to extend the CDockablePane and override in this class the following events:
virtual BOOL CanFloat() const;
virtual BOOL CanBeClosed() const;
virtual BOOL CanAutoHide() const;
so that they return FALSE;
for more information see MSDN Customization Tips for the MFC Extensions

Try changing the dwControlBarStyle when you create the window (with CDockablePane::Create).

Another solution is, just call
CBasePane::SetControlBarStyle(AFX_CBRS_RESIZE|AFX_CBRS_CLOSE);

Related

Custom draw ListView Items without border per how TListView itself does it

In a custom control, I custom-draw TListView items myself in the TListView.OnAdvancedCustomDrawItem event. This works well.
I have been experimenting with several Theme classes and parts. For instance, when I use:
HTHEME Theme = OpenThemeData(Handle, L"Explorer::ListView") ;
DrawThemeBackground (Theme, Sender->Canvas->Handle, LVP_LISTITEM, LISS_NORMAL, &ItemRect, NULL);
I get what is to be expected, per Theme explorer (do notice the borders around the item):
But, if I look at a proper VCL TListView object, similar items are painted without a border. I expected this control to use the same Theme class and part. Is that not the case? If so, what class/part should I use to mimic the behavior?
This is what I see (notice the borders in the custom control vs the absence of borders in the true TListView control just below it:
I'm actually getting a 'nicer' result with LVP_GROUPHEADER, but I'm still very curious about LVP_LISTITEM.
FYI, using LVP_GROUPHEADER instead of LVP_LISTITEM. It works well for this type control, so a nice alternative, but I'm still very curious as to why the real ListView control paints no borders using LVP_LISTITEM (I THINK).
Perhaps I should add that I still use old C++ Builder 2009 for this project. This is a low effort attempt to improve the control to give it a life beyond W10 (Especially W11 where current MENU / MENU_POPUPITEM choice is not kind on the eyes). PS. having more problems with TPopupMenu now .. but that's another topic I guess.
A simple code example (not same as in project but showing the border):
#include "uxtheme.h"
#include "Vsstyle.h"
// Project includes uxtheme.lib
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
HTHEME Theme = OpenThemeData(Handle, L"Explorer::ListView") ;
TRect ItemRect = Image1->ClientRect ;
DrawThemeBackground (Theme, Image1->Canvas->Handle, LVP_LISTITEM, LISS_NORMAL, (tagRECT*)&ItemRect, NULL);
CloseThemeData(Theme) ;
}
//---------------------------------------------------------------------------

How to turn Windows system network icon on/off programmatically

I want to turn the system network icon on/off in my application likes what we can do via control panel. I know the "HideSCANetwork" registry item, but to use this solution I need to restart the explorer after changing the setting. Is there any other solution which can do this seamlessly like the system?
There is no official API for doing thois. The reason for this is that Microsoft wanted to give the user the ability to keep their notification area from becoming too full. The problem being too many applications starting notification icons that the user doesn't care for.
Since many users don't know how to get rid of these icons, Microsoft decided to help by hiding them by default. If applications had access to these hide/show settings then applications would simply show the notifications by default and we'd be back where we started. So there is no mechanism provided for modifying these settings programmatically.
You want to do something different that sounds equally malicious, namely to hide an important system icon. If you are determined to do this then you can reverse engineer how the setting is stored (likely in the registry) and change the setting that way. However, you'll be going against the system design should you do so.
Now I find a imperfect solution. The basic idea comes from here:
http://www.codeproject.com/Articles/10807/Shell-Tray-Info-Arrange-your-system-tray-icons
Some tips:
This solution supports Win 7, you can remove XP checking code.
On wow64, you need to change the struct TRAYDATA and use TBUTTON64:
struct TRAYDATA
{
DWORD64 hwnd;
UINT uID;
UINT uCallbackMessage;
DWORD Reserved[2];
DWORD64 hIcon;
};
typedef struct _TBBUTTON64
{
int iBitmap;
int idCommand;
BYTE fsState;
BYTE fsStyle;
BYTE bReserved[6];
DWORD64 dwData;
DWORD64 iString;
} TBBUTTON64, NEAR* PTBBUTTON64, *LPTBBUTTON64;
typedef const TBBUTTON64 *LPCTBBUTTON64;
When you find the icon you want to hide(By using the tip text plus the owner process), send a TB_HIDEBUTTON message to the notification area window.
The imperfect part is that the tray icon will be hidden, but the notification area will not resize. So there is a blank area on the notification area.

Change color of background and title in MFC Control

I want to change text color and background color for my EDIT CONTROL, STATIC CONTROL and BUTTON CONTROL in MFC application. The control is in a CDialogEx dialogue .
I try to add the OnCtlColor (with wizard in visual studio, on the WM_CTLCOLR message) but I can't set the color of may static control and button control.
I put also a break point in the OnCtlColor function (in the IF construct), but I don't receive anything.
I also tried to use the SetTextColor function retrieving the handle of the control from GetDlgItem, but I can't change the color as I want.
Pleas help me.
I can assert that I tried to use in OnCtlColor in a CDialog and it worked for the static and for the edit controls.
All you have to do is:
For changing background color, you need to create a brush that still exists outside that function and return its HBRUSH with
return (HBRUSH) m_brush.GetSafeHandle();
So you have to make a variable (m_brush in this code) that is member or a static (I recommend the first), and in the dialog initialization you have to create the brush you want.
I thought maybe some controls will not work with this, and for those I also did
pDC->SetBkColor(RGB(0,0,255));
But seems to do nothing; it is in the code for safety.
For changing the text color,I did
pDC->SetTextColor(RGB(255,0,0));
These experiences worked well for edits and statics, but did not work at all for groupboxes!
Groupboxes are a strange entity in MFC, some kind of a platyplus: they are a CButton with the BS_GROUPBOX, but in this function, its nCtlColor is CTLCOLOR_STATIC instead of CTLCOLOR_BTN! I did this for them
UINT nStyle = (UINT)(pWnd->GetStyle() & 0x0F);
if(nStyle == BS_GROUPBOX)
{
return (HBRUSH) m_brush2.GetSafeHandle();
}
and what got painted was the little rectangle behind the groupbox title!
I could not get the text colour of groupboxes changed!
If you have groupboxes and it is really important to change their titles' text color, you can get the one from http://www.codeproject.com/Articles/29016/XGroupBox-an-MFC-groupbox-control-to-display-text and get its essential code parts: to be derived from CStatic, the OnPaint() and DrawItem() methods. Do not forget also the ON_WM_PAINT() on the message map. I don't know if the OnEraseBkgnd() and its is ON_WM_ERASEBKGND() message mapping are so essential.
It is also needed to change them to be Static text controls in the resources, declare a XGroupBox variable and do a DDX_Control of it.
I tested it and it really works.
For buttons, with CButtons it did not work. But, for each button, I simply declared a CMFCButton variable in the class and did a DDX_Control of each one. After, I had two choices:
Set its m_bTransparent property to TRUE in the form constructor (search this variable on afxbutton.cpp file for reference) for the ones I wanted to have the same color as the form (I also painted the form; in my case I was implementing themes on an application)
Set the Background color with SetFaceColor() and set the Text Color with SetTextColor() in form initialization.
When the CMFCButton does not have these things set, it got its color from theme blending of the currently selected CMFCVisualManager.
Note: I also replaced my CSpinButton entities with CMFCSpinButon ones, because I wanted colors from the selected theme.
In the OnCtlColor, the nCtlColor variable is important because it will allow you to personalize different colors to different types, without testing dynamic_cast success or failure for every control.
Do not forget to add ON_WM_CTLCOLOR() to your message map.
UPDATE 1:
After following the advice of the accepted answer on http://social.msdn.microsoft.com/Forums/vstudio/en-US/53f47162-078a-418f-8067-ee61a81ceeac/checkbox-transparent-color-not-working-in-vs2008?forum=vcgeneral , I did my own Groupbox class, and now it is like:
class CMyGroupBox: public CButton
{
protected:
virtual void PreSubclassWindow()
{
SetWindowTheme(*this, _T(""), _T(""));
#pragma comment(lib, "UxTheme.lib")
}
};
I just declared one of this, and did DDX_Control with its respective control ID, and now I can see the text in the color I supplied to SetTextColor. If you return a HBRUSH for this control, what gets painted is a non-filled rectangle drawn around the groupbox's title.
UPDATE 2: I just generalized the CMyGroupBox to be CMyButton, for using its PreSubClassWindow method not only in groupboxes, but also in checkboxes and buttons. In checkboxes it works well, in buttons, I am not so satisfied with the results.
UPDATE 3: I was trying to remove some weird effect on the rendering of the text and I just commented the pDC->SetBkColor(RGB(0,0,255)); line; the result was an ugly while rectangle behind the text :( . Then I replaced it with pDC->SetBkMode(TRANSPARENT); and I also see tht weird effect :(
UPDATE 4: In order to avoid to have to declare all my checkboxes, groupboxes and buttons as the class that contains the PreSubClassWindow method, I researched and discovered that it is not needed to do it. The code
SetThemeAppProperties(0);
#pragma comment(lib, "UxTheme.lib")
AfxGetMainWnd()->SendMessage(WM_THEMECHANGED, 0U, 0L);
disables theming for all controls at the whole application level.

What would be the better way to do a function pointer for GUI input?

I Am currently working on an open source Game engine in C for people to learn from etc and i was wondering what would be the best way to do the input for The UI system via mouse clicks, key press's etc.
Currently i have the the ui system's input using function pointers where to set a function the user would just go.
button1.mousepress = button1_press;
then if the user clicked button1 it would loop through to find button 1 then do button1's click event. however i need it to go to a event inside of the control then to the users control. The way i have the function pointers setup is as follows.
struct widget
{
//contains control special data
void *control;
//contains the parent of the widget.
widget *parent;
//contains events for quick calling
void(*draw)(widget *);
void(*mousepress)(widget *,int,int);
void(*mouserelease)(widget *,int,int);
void(*mousewheel)(widget *,int);
void(*keypressed)(widget *,int,int);
//hidden and shown arrays
widget_array shown;
widget_array hidden;
vector2ui pos;
vector2ui actualpos;
vector2ui originalpos;
vector2i imgpos;
image img;
uint16 width;
uint16 height;
uint8 type;
sbool action;
};
As you can see the function pointers are not generic at the moment, so if i have to make them generic i will. other than that what would be the best way to set the function pointers up to allow them to go into the gui controls Event then go to the user made
button1.mousepress. Any ideas on what the best method for doing thins would be. A friend of mine suggested Chaining but i could not figure out how chaining works....
Thank you for any of you who read through this, as well as thank you to those whom will help.

How can I force Aero to draw a borderless window as if it were active, even if it's not?

I'd like to have the same effect as the windows 7 taskbar.
I've looked in this question:
Keep Window Looking Active
It works great but only if the window has a non-client area.
My window is border-less and the content of it (just a black background) is rendered as it is inactive, no matter what I do.
I've set my window flags just as Windows 7 taskbar but it didn't help.
My only thought at the moment is to draw it with borders and just clip them, is there a better way to achieve what I want?
EDIT 1:
Clipping didn't work, after clipping the borders the window content was rendered as inactive window.
How the hell does windows 7 task-bar works then?
EDIT2:
Adding some photos to explain myself better, The following window content is a black background.
That's an inactive window (the content is rendered kinda dark):
That's an active window:
If the window has no client area the content is always rendered as inactive window however the windows Taskbar is always rendered as active window and it doesn't have any NC area (at least according to spy++). That's what I'm trying to mimic.
EDIT3:
Sharing my recent discoveries.
explorer.exe main window is frameless and has the following flags:
I dived into the explorer's process dwmapi.dll exported functions:
it uses DwmEnableBlurBehindWindow, just as I do.
I've checked the undocumented ordinal functions and none of them is related to rendering the aero glass as active.
Could it be the DWM rules don't apply to explorer?
Tricky one..
set the NCRenderingPolicy to Enabled with the "DwmSetWindowAttribute" API.
http://msdn.microsoft.com/en-us/library/windows/desktop/aa969524(v=vs.85).aspx
[DllImport("dwmapi.dll", PreserveSig = false)]
public static extern int DwmSetWindowAttribute(IntPtr hwnd, int attr, ref int attrValue, int attrSize);
[Flags]
public enum DwmWindowAttribute
{
NCRenderingEnabled = 1,
NCRenderingPolicy,
TransitionsForceDisabled,
AllowNCPaint,
CaptionButtonBounds,
NonClientRtlLayout,
ForceIconicRepresentation,
Flip3DPolicy,
ExtendedFrameBounds,
HasIconicBitmap,
DisallowPeek,
ExcludedFromPeek,
Last
}
[Flags]
public enum DwmNCRenderingPolicy
{
UseWindowStyle,
Disabled,
Enabled,
Last
}
public static bool SetNCRenderingActive(IntPtr Handle)
{
int renderPolicy = (int)DwmNCRenderingPolicy.Enabled;
return (DwmSetWindowAttribute(Handle, (int)DwmWindowAttribute.NCRenderingPolicy, ref renderPolicy, sizeof(int) ) == 0);
}

Resources