How can we detect WM_LBUTTONDBLCLK on a button (ex. ID_FILE_NEW) on a Toolbar?
This seems to be straight forward with PreTranslateMessage(). I have tested with this code snippet.
BOOL CMainFrame::PreTranslateMessage(MSG* pMsg)
{
// Detect Clicks in Toolbar detektieren
if (pMsg->hwnd == m_wndToolBar.GetSafeHwnd())
{
if (pMsg->message == WM_LBUTTONDBLCLK)
{
CPoint pt = pMsg->pt;
m_wndToolBar.ScreenToClient(&pt);
int nIdx = m_wndToolBar.CommandToIndex(ID_FILE_NEW);
CRect rcIdx;
m_wndToolBar.GetItemRect(nIdx, &rcIdx);
if (rcIdx.PtInRect(pt))
{
MessageBox(_T("yupii double click detected"));
return TRUE;
}
}
}
return CMDIFrameWndEx::PreTranslateMessage(pMsg);
}
Related
I'm checking if a button is checkbox of 32bit process on 64bit windows10.
The problem is that I can not distingush checkbox from normal button.
The buttons are different in Window-Detective:
(After I restart the application, even Window-Detective shows it is a button now!)
But the checkbox can't be recognized as checkbox in Spy++
BS_CHECKBOX is not listed.
Code (compiled as 32bit):
TEST_METHOD(ShouldCheckStyle) {
auto styleOfButton = ::GetWindowLongPtr((HWND)0x003F06E8, GWL_STYLE);
auto styleOfCheckbox = ::GetWindowLongPtr((HWND)0x01101642, GWL_STYLE);
auto bsOfButton = styleOfButton & BS_TYPEMASK;
auto bsOfCheckbox = styleOfCheckbox & BS_TYPEMASK;
auto resultOfButton = (bsOfButton == BS_CHECKBOX);
auto resultOfCheckbox = (bsOfCheckbox == BS_CHECKBOX);
auto debugger = 0;
}
Debug output
The code indicates they both have BS_OWNERDRAW. The above behaves the same for the button and the checkbox.
The weird thing is Window-Detective can recognize the style of checkbox. The code is same as I used above. Here's a piece of code:
Window* WindowManager::createWindow(HWND handle) {
WindowClass* windowClass = getWindowClassFor(handle);
String className = windowClass->getName().toLower();
if (className == "button") {
LONG typeStyle = GetWindowLong(handle, GWL_STYLE) & BS_TYPEMASK;
switch (typeStyle) {
case BS_CHECKBOX:
case BS_AUTOCHECKBOX:
case BS_3STATE:
case BS_AUTO3STATE: {
return new CheckBox(handle, windowClass);
}
case BS_RADIOBUTTON:
case BS_AUTORADIOBUTTON: {
return new RadioButton(handle, windowClass);
}
case BS_GROUPBOX: {
return new GroupBox(handle, windowClass);
}
default: {
// If none of the above is true, then the control is just a Button
return new Button(handle, windowClass);
}
}
}
After some discussion, you can use GetWindowText to get the text from each control and compare the specific text.
BS_CHECKBOX cannot be detected from the properties of the "checkbox" control beacuse of BS_OWNERDRAW.
Creates an owner-drawn button. The owner window receives a WM_DRAWITEM
message when a visual aspect of the button has changed. Do not combine
the BS_OWNERDRAW style with any other button styles.
Try the below code:
WCHAR str1[20];
WCHAR str2[] = L"Agree me";
GetWindowText(hwnd_checkbox, str1, 256);
if (_tcscmp(str1, str2) == 0)
{
//it is checkbox
}
else
{
//it isn't checkbox
}
After you get the correct control handle of the checkbox, you can use SendDlgItemMessage or SendMessage to send BM_SETCHECK check message.
SendMessage(hwnd_checkbox, BM_SETCHECK, BST_CHECKED, 0);
In the MainActivity OnCreate, I set the color of the StatusBar using:
Window.SetStatusBarColor(Resources.GetColor(Resource.Color.colorPrimary));
For the specific pages, I need to set the StatusBar color trasparent.
Is possible to do that in a Android custom rendered class?
EDIT:
my OnLayout method on custom ANdorid
protected override void OnLayout(bool changed, int l, int t, int r, int b)
{
CustomNavigation.IgnoreLayoutChange = true;
base.OnLayout(changed, l, t, r, b);
CustomNavigation.IgnoreLayoutChange = false;
int containerHeight = b - t;
PageController.ContainerArea = new Rectangle(0, 0, Context.FromPixels(r - l), Context.FromPixels(containerHeight));
if (Element?.Navigation?.NavigationStack.Count == 1)
{
CustomNavigation.BarBackgroundColor = Color.Transparent;
//HERE I NEED TO HAVE STATUS AR TRANSPARENT
}
if (Element?.Navigation?.NavigationStack.Count > 1)
{
PageController.ContainerArea = new Rectangle(0, 60, Context.FromPixels(r - l), Context.FromPixels(containerHeight));
CustomNavigation.BarBackgroundColor = Color.FromHex("#006CA6");
}
for (var i = 0; i < ChildCount; i++)
{
AView child = GetChildAt(i);
if (child is Android.Support.V7.Widget.Toolbar)
{
continue;
}
child.Layout(0, 0, r, b);
}
}
Status bar appearance is about its background and text colours. Both properties have their own limitations on different platforms, however, we could manipulate both with the solution described below.
Our goal is simple, we want to be able to switch the status bar appearance between LightTheme and DarkTheme at runtime:
Define an interface in your shared code:
public interface IStatusBarStyleManager
{
void SetLightTheme();
void SetDarkTheme();
}
Since Android Lollipop (21) it is possible to set a custom status bar background colour by simply defining it in style.xml with a key colorPrimaryDark or programmatically, Since Android M (23) it is possible to set a predefined status bar text colour theme to light or dark.
Android code:
public class StatusBarStyleManager : IStatusBarStyleManager
{
public void SetDarkTheme()
{
if (Build.VERSION.SdkInt >= BuildVersionCodes.M)
{
Device.BeginInvokeOnMainThread(() =>
{
var currentWindow = GetCurrentWindow();
currentWindow.DecorView.SystemUiVisibility = 0;
currentWindow.SetStatusBarColor(Android.Graphics.Color.DarkCyan);
});
}
}
public void SetLightTheme()
{
if (Build.VERSION.SdkInt >= BuildVersionCodes.M)
{
Device.BeginInvokeOnMainThread(() =>
{
var currentWindow = GetCurrentWindow();
currentWindow.DecorView.SystemUiVisibility = (StatusBarVisibility)SystemUiFlags.LightStatusBar;
currentWindow.SetStatusBarColor(Android.Graphics.Color.LightGreen);
});
}
}
Window GetCurrentWindow()
{
var window = CrossCurrentActivity.Current.Activity.Window;
// clear FLAG_TRANSLUCENT_STATUS flag:
window.ClearFlags(WindowManagerFlags.TranslucentStatus);
// add FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS flag to the window
window.AddFlags(WindowManagerFlags.DrawsSystemBarBackgrounds);
return window;
}
}
I am using the Current Activity Plugin by James Montemagno to get the reference of the current activity.
iOS code:
In iOS the status bar background colour by default matching the colour of the navigation bar. In other words, we don’t have to explicitly set the background colour of the status bar if we want it to match the background colour of the navigation bar. Since iOS 7 it is possible to set a predefined status bar text colour theme to light or dark. However, we will have to manipulate the Info.plist. Since status bar behaviour is determined by view controllers by default, we have to disable this:
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
Next, we can define a default text colour theme:
<key>UIStatusBarStyle</key>
<string>UIStatusBarStyleDefault</string>
public class StatusBarStyleManager : IStatusBarStyleManager
{
public void SetDarkTheme()
{
Device.BeginInvokeOnMainThread(() =>
{
UIApplication.SharedApplication.SetStatusBarStyle(UIStatusBarStyle.LightContent, false);
GetCurrentViewController().SetNeedsStatusBarAppearanceUpdate();
});
}
public void SetLightTheme()
{
Device.BeginInvokeOnMainThread(() =>
{
UIApplication.SharedApplication.SetStatusBarStyle(UIStatusBarStyle.Default, false);
GetCurrentViewController().SetNeedsStatusBarAppearanceUpdate();
});
}
UIViewController GetCurrentViewController()
{
var window = UIApplication.SharedApplication.KeyWindow;
var vc = window.RootViewController;
while (vc.PresentedViewController != null)
vc = vc.PresentedViewController;
return vc;
}
}
Goodluck
Revert in case of queries.
Its very common problem in iOS mobile development and that is while you are done with your UI and It contains too many UITextFields, If you try to input value in UITextFields those are added center bottom of the screen; these fields hides behind the keyboard. How can we get rid of this general problem?
You could use the AddObserver method in NSNotificationCenter for when keyboard is visible and hidden.
sample code(FYI: Got the code below from another post sometime last year, I can't remember link to the post but it works fine.)
Call the AddObserver in your viewdidload method
// Keyboard popup NSNotificationCenter.DefaultCenter.AddObserver(UIKeyboard.DidShowNotification, KeyBoardUpNotification);
// Keyboard Down NSNotificationCenter.DefaultCenter.AddObserver(UIKeyboard.WillHideNotification, KeyBoardDownNotification);
you can add the methods below in your base controller base if you have one
public void KeyBoardUpNotification(NSNotification notification) {
CGRect keyboardSize = UIKeyboard.BoundsFromNotification(notification);
// Find what opened the keyboard
foreach (UIView view in this.View.Subviews) {
if (view.IsFirstResponder)
activeview = view;
}
bottom = (activeview.Frame.Y + activeview.Frame.Height + offset);
scrollamount = (keyboardSize.Height - (View.Frame.Size.Height - bottom));
if (scrollamount > 0) {
moveViewUp = true;
MoveView(moveViewUp);
} else {
moveViewUp = false;
}
}
public void KeyBoardDownNotification(NSNotification notification) {
if (moveViewUp) {
MoveView(false);
}
}
private void MoveView(bool move) {
UIView.BeginAnimations(string.Empty, IntPtr.Zero);
UIView.SetAnimationDuration(0.3);
CGRect frame = View.Frame;
if (move) {
frame.Y -= scrollamount;
} else {
frame.Y += scrollamount;
scrollamount = 0;
}
View.Frame = frame;
UIView.CommitAnimations();
}
I have used a nuget package to get rid of this problem. I have overrides two methods and initialized code inside these methods.
Download KeyboardHandler and use as following:
using KeyboardHandler;
public override void ViewWillAppear(bool animated)
{
base.ViewWillAppear(animated);
this.yourScrollView.SubscribeKeyboardManaqger();
}
public override void ViewWillDisappear(bool animated)
{
base.ViewWillDisappear(animated);
this.yourScrollView.UnsubscribeKeyboardManaqger();
}
I want extend an System.Windows.Forms.Panel(just inherit) and using a custom ControlDesigner.
I use a very minimalistic ControlDesigner implementation, just overwrite GetHitTest.
The problem is my custom panel instance is not ready to contains child controls any longer.
I play a little bit with AssociatedComponents but without effect. Remove custom designer attribute and it works great.
can someone help me to pin point whats wrong ???
[Designer(typeof(MyPanelDesigner)), ToolboxItem(true)]
public class MyPanel : System.Windows.Forms.Panel
{
// empty except for OnPaint
}
internal class DrawPanelDesigner : ControlDesigner
{
private MyPanel ParentControl
{
get
{
return Control as MyPanel;
}
}
public override System.Collections.ICollection AssociatedComponents
{
get
{
return ParentControl.Controls;
}
}
protected override bool GetHitTest(System.Drawing.Point point)
{
// hit detection for some owner drawed items in OnPaint
point = ParentControl.PointToClient(point);
var item = ParentControl.View.GetItemFromViewPoint(point.X, point.Y, true);
return null != item;
}
You are using the wrong designer. Try inheriting from the ScrollableControlDesigner instead:
internal class DrawPanelDesigner : ScrollableControlDesigner {
public DrawPanelDesigner() {
AutoResizeHandles = true;
}
private MyPanel ParentControl {
get {
return Control as MyPanel;
}
}
protected Pen BorderPen {
get {
Color penColor = Control.BackColor.GetBrightness() < .5 ?
ControlPaint.Light(Control.BackColor) :
ControlPaint.Dark(Control.BackColor);
Pen pen = new Pen(penColor);
pen.DashStyle = DashStyle.Dash;
return pen;
}
}
protected virtual void DrawBorder(Graphics graphics) {
Panel panel = (Panel)Component;
if (panel == null || !panel.Visible) {
return;
}
Pen pen = BorderPen;
Rectangle rc = Control.ClientRectangle;
rc.Width--;
rc.Height--;
graphics.DrawRectangle(pen, rc);
pen.Dispose();
}
protected override void OnPaintAdornments(PaintEventArgs pe) {
Panel panel = (Panel)Component;
if (panel.BorderStyle == BorderStyle.None) {
DrawBorder(pe.Graphics);
}
base.OnPaintAdornments(pe);
}
}
I have a need to add a custom action (say ‘About’ clicking which a QMessageBox needs to be displayed) in the system menu shown when the icon on the title bar of a QDialog is clicked. How do I achieve this?
Regards,
Bharath
You cannot do it with Qt because it's OS specific. But you can use GetSystemMenu and AppendMenu functions in Windows to modify the menu and then catch events that then item is clicked.
Here is a simple example from here. It appends a separator and an about item to the menu:
#include "windows.h"
// IDM_ABOUTBOX must be in the system command range
// (IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX)
// and (IDM_ABOUTBOX < 0xF000)
#define IDM_ABOUTBOX 0x0010
MyWidget::MyWidget() : QMainWindow()
{
...
HMENU hMenu = ::GetSystemMenu(winId(), FALSE);
if (hMenu != NULL)
{
::AppendMenuA(hMenu, MF_SEPARATOR, 0, 0);
::AppendMenuA(hMenu, MF_STRING, IDM_ABOUTBOX, "About MyApp...");
}
...
}
bool MyWidget::winEvent(MSG *m, long *result)
{
if (m->message == WM_SYSCOMMAND)
{
if ((m->wParam & 0xfff0) == IDM_ABOUTBOX)
{
*result = 0;
// open About dialog
about();
return (true);
}
}
return (false);
}
PRO-file:
LIBS += -lUser32