问:
Which method need to override to round the corner of NotiIcon's ContextMenuStrip?
In windows 11, I have found that almost every Systray Icon's Context Menu has a round corner.
As there is no Systray Menu for WPF application, I have used Window's form NotiIcon and ContextMenuStrip.
I have fully customized ToolStripProfessionalRenderer with ProfessionalColorTable to support dark mode
as per clients' requirements. Now I'm looking for rounding the corner. I was used "RoundedEdges = true;"
but not worked. I need to know exactly which method need to override to round the corner of ContextMenuStrip.

Here below is my renderer sample code.

```<code>   ///Menu Renderer
public class MenuRenderer : ToolStripProfessionalRenderer
{
    //Fields
    private Color primaryColor;
    private Color textColor;
    private int arrowThickness;
    private WindowsTheme systrayTheme;

    [Browsable(false)]
    public WindowsTheme SystrayTheme
    {
        get { return systrayTheme; }
        set { systrayTheme = value; }
    }

    //Constructor
    public MenuRenderer(bool isMainMenu, Color primaryColor, Color textColor, Color menuItemMouseOverColor, Color menuItemMouseOverBorderColor, WindowsTheme theme)
        : base(new MenuColorTable(isMainMenu, primaryColor, menuItemMouseOverColor, menuItemMouseOverBorderColor, theme))
    {
        RoundedEdges = true;

        this.primaryColor = primaryColor;
        this.systrayTheme = theme;

        if (isMainMenu)
        {
            arrowThickness = 2;
            if (textColor == Color.Empty) //Set Default Color
                this.textColor = Color.Gainsboro;
            else//Set custom text color
                this.textColor = textColor;
        }
        else
        {
            arrowThickness = 1;
            if (textColor == Color.Empty) //Set Default Color
                this.textColor = Color.DimGray;
            else//Set custom text color
                this.textColor = textColor;
        }
    }

    //Overrides
    protected override void OnRenderItemText(ToolStripItemTextRenderEventArgs e)
    {
        base.OnRenderItemText(e);
        e.Item.ForeColor = e.Item.Selected ? Color.White : textColor;
    }

    protected override void OnRenderArrow(ToolStripArrowRenderEventArgs e)
    {
        //Fields
        var graph = e.Graphics;
        var arrowSize = new Size(5, 10);
        var arrowColor = e.Item.Selected ? Color.White : primaryColor;
        var rect = new Rectangle(e.ArrowRectangle.Location.X, (e.ArrowRectangle.Height - arrowSize.Height) / 2,
            arrowSize.Width, arrowSize.Height);
        using (GraphicsPath path = new GraphicsPath())
        using (Pen pen = new Pen(arrowColor, arrowThickness))
        {
            //Drawing
            graph.SmoothingMode = SmoothingMode.AntiAlias;
            path.AddLine(rect.Left, rect.Top, rect.Right, rect.Top + rect.Height / 2);
            path.AddLine(rect.Right, rect.Top + rect.Height / 2, rect.Left, rect.Top + rect.Height);
            graph.DrawPath(pen, path);
        }
    }

    protected override void OnRenderGrip(ToolStripGripRenderEventArgs e)
    {
        Rectangle rectangle = new Rectangle(e.AffectedBounds.X, e.AffectedBounds.Y, e.AffectedBounds.Width, e.AffectedBounds.Height);
        GraphicsPath graphicsPath = RoundedRect(rectangle, 8);

        using (Pen pen = new Pen(Color.Green,5))
        {
            e.Graphics.DrawPath(pen, graphicsPath);
            //e.Graphics.FillPath(pen.Brush, graphicsPath);
        }
    }

    protected override void OnRenderToolStripPanelBackground(ToolStripPanelRenderEventArgs e)
    {
        //base.OnRenderToolStripPanelBackground(e);
        Rectangle rectangle = new Rectangle(e.ToolStripPanel.Location.X, e.ToolStripPanel.Location.Y,
            e.ToolStripPanel.ClientRectangle.Width, e.ToolStripPanel.ClientRectangle.Height);
        GraphicsPath graphicsPath = RoundedRect(rectangle, 8);

        using (Pen pen = new Pen(Color.Green, 5))
        {
            //e.Graphics.DrawPath(pen, graphicsPath);
            e.Graphics.FillPath(pen.Brush, graphicsPath);
        }
    }

    protected override void OnRenderStatusStripSizingGrip(ToolStripRenderEventArgs e)
    {
        //base.OnRenderStatusStripSizingGrip(e);
        Rectangle rectangle = new Rectangle(e.AffectedBounds.X, e.AffectedBounds.Y, e.AffectedBounds.Width, e.AffectedBounds.Height);
        GraphicsPath graphicsPath = RoundedRect(rectangle, 8);

        using (Pen pen = new Pen(Color.Green,5))
        {
            e.Graphics.DrawPath(pen, graphicsPath);
            //e.Graphics.FillPath(pen.Brush, graphicsPath);
        }
    }

    protected override void OnRenderToolStripBorder(ToolStripRenderEventArgs e)
    {
        //Fields
        //var graph = e.Graphics;
        //var borderZise = new Size(e.AffectedBounds.Width + 10, e.AffectedBounds.Height + 10);
        //var borderColor = Color.DeepPink;

        //var rect = new Rectangle(e.AffectedBounds.X, (e.AffectedBounds.Height - borderZise.Height) / 2,
        //    borderZise.Width, borderZise.Height);
        //using (GraphicsPath path = new GraphicsPath())
        //using (Pen pen = new Pen(borderColor, arrowThickness))
        //{
        //    //Drawing
        //    graph.SmoothingMode = SmoothingMode.AntiAlias;
        //    path.AddLine(rect.Left, rect.Top, rect.Right, rect.Top + rect.Height / 2);
        //    path.AddLine(rect.Right, rect.Top + rect.Height / 2, rect.Left, rect.Top + rect.Height);
        //    graph.DrawPath(pen, path);
        //}
        //DrawRoundedRectangle(e.Graphics, e.AffectedBounds.X, e.AffectedBounds.Y, e.AffectedBounds.Width - 5, e.AffectedBounds.Height, 15, Color.Red);

        //Rectangle rectangle = new Rectangle(e.AffectedBounds.X, e.AffectedBounds.Y, e.AffectedBounds.Width, e.AffectedBounds.Height);
        //GraphicsPath graphicsPath = RoundedRect(rectangle, 8);

        //using (Pen pen = new Pen(Color.Green, 2))
        //{
        //    //e.Graphics.DrawPath(pen, graphicsPath);
        //    e.Graphics.FillPath(pen.Brush, graphicsPath);
        //}
    }

    public GraphicsPath RoundedRect(Rectangle bounds, int radius)
    {
        int diameter = radius * 2;
        Size size = new Size(diameter, diameter);
        Rectangle arc = new Rectangle(bounds.Location, size);
        GraphicsPath path = new GraphicsPath();

        if (radius == 0)
        {
            path.AddRectangle(bounds);
            return path;
        }

        // top left arc
        path.AddArc(arc, 180, 90);

        // top right arc
        arc.X = bounds.Right - diameter;
        path.AddArc(arc, 270, 90);

        // bottom right arc
        arc.Y = bounds.Bottom - diameter;
        path.AddArc(arc, 0, 90);

        // bottom left arc
        arc.X = bounds.Left;
        path.AddArc(arc, 90, 90);

        path.CloseFigure();
        return path;
    }
}

////////Custom Menu
public class CustomContextMenu : ContextMenuStrip
{
    //Fields
    private bool isMainMenu;
    private int menuItemHeight = 20;
    private int menuItemWidth = 20;
    private Color menuItemTextColor = Color.Empty;
    private Color primaryColor = Color.Empty;
    private Color MouseOverColor = Color.Empty;
    private Color MouseOverBorderColor = Color.Empty;
    private WindowsTheme systrayTheme = WindowsTheme.Light;
    private Bitmap menuItemHeaderSize;

    //Constructor
    public CustomContextMenu()
    {

    }

    //Properties
    [Browsable(false)]
    public bool IsMainMenu
    {
        get { return isMainMenu; }
        set { isMainMenu = value; }
    }

    [Browsable(false)]
    public int MenuItemHeight
    {
        get { return menuItemHeight; }
        set { menuItemHeight = value; }
    }

    [Browsable(false)]
    public int MenuItemWidth
    {
        get { return menuItemWidth; }
        set { menuItemWidth = value; }
    }

    [Browsable(false)]
    public Color MenuItemTextColor
    {
        get { return menuItemTextColor; }
        set { menuItemTextColor = value; }
    }

    [Browsable(false)]
    public Color PrimaryColor
    {
        get { return primaryColor; }
        set { primaryColor = value; }
    }

    [Browsable(false)]
    public Color MenuItemMouseOverColor
    {
        get { return MouseOverColor; }
        set { MouseOverColor = value; }
    }

    [Browsable(false)]
    public Color MenuItemMouseOverBorderColor
    {
        get { return MouseOverBorderColor; }
        set { MouseOverBorderColor = value; }
    }

    [Browsable(false)]
    public WindowsTheme SystrayTheme
    {
        get { return systrayTheme; }
        set { systrayTheme = value; }
    }

    //Private methods
    private void LoadMenuItemHeight()
    {
        if (isMainMenu)
            menuItemHeaderSize = new Bitmap(menuItemWidth, menuItemHeight);
        else menuItemHeaderSize = new Bitmap(menuItemWidth-5, menuItemHeight);

        foreach (Forms.ToolStripMenuItem menuItemL1 in this.Items)
        {
            menuItemL1.ImageScaling = ToolStripItemImageScaling.None;
            if (menuItemL1.Image == null) menuItemL1.Image = menuItemHeaderSize;

            foreach (Forms.ToolStripMenuItem menuItemL2 in menuItemL1.DropDownItems)
            {
                menuItemL2.ImageScaling = ToolStripItemImageScaling.None;
                if (menuItemL2.Image == null) menuItemL2.Image = menuItemHeaderSize;

                foreach (Forms.ToolStripMenuItem menuItemL3 in menuItemL2.DropDownItems)
                {
                    menuItemL3.ImageScaling = ToolStripItemImageScaling.None;
                    if (menuItemL3.Image == null) menuItemL3.Image = menuItemHeaderSize;

                    foreach (Forms.ToolStripMenuItem menuItemL4 in menuItemL3.DropDownItems)
                    {
                        menuItemL4.ImageScaling = ToolStripItemImageScaling.None;
                        if (menuItemL4.Image == null) menuItemL4.Image = menuItemHeaderSize;
                        ///Level 5++
                    }
                }
            }
        }
    }

    //Overrides
    protected override void OnHandleCreated(EventArgs e)
    {
        base.OnHandleCreated(e);
        if (this.DesignMode == false)
        {
            switch (SystrayTheme)
            {
                case WindowsTheme.Light:
                    {
                        menuItemTextColor = Color.Black;
                    }
                    break;
                case WindowsTheme.Dark:
                    {
                        menuItemTextColor = Color.White;
                    }
                    break;
                case WindowsTheme.HighContrast:
                    {
                        menuItemTextColor = Utility.ToDrawingColor(System.Windows.SystemColors.MenuTextColor);
                    }
                    break;
            }

            this.Renderer = new MenuRenderer(isMainMenu, primaryColor, menuItemTextColor, MouseOverColor, MouseOverBorderColor, SystrayTheme);
            LoadMenuItemHeight();
        }
    }
 }
</code>```

Update:

Recently I was tried to override OnPaint() method. But the round corner is not smooth and also sub-menu is not rounded.

```<code>    private GraphicsPath GetGraphicsPath(RectangleF rect,float radious)
    {
        GraphicsPath path = new GraphicsPath();
        path.StartFigure();
        path.AddArc(rect.X, rect.Y, radious, radious, 180, 90);
        path.AddArc(rect.Width - radious, rect.Y, radious, radious, 270, 90);
        path.AddArc(rect.Width - radious, rect.Height - radious, radious, radious, 0, 90);
        path.AddArc(rect.X, rect.Height - radious, radious, radious, 90, 90);

        path.CloseFigure();

        return path;
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);
        e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;

        RectangleF rectSurface = new RectangleF(0, 0, this.Width, this.Height);
        RectangleF rectBorder = new RectangleF(1, 1, this.Width - 0.8F, this.Height - 1);

        if (borderRadius > 2) //Rounder
        {
            using (GraphicsPath pathSurface = GetGraphicsPath(rectSurface, borderRadius))
            using (GraphicsPath pathBorder = GetGraphicsPath(rectBorder, borderRadius - 1F))
            using (Pen penSurface = new Pen(this.BackColor, 2))
            using (Pen penBorder = new Pen(borderColor, borderSize))
            {
                penBorder.Alignment = PenAlignment.Inset;
                //Menu surface
                this.Region = new Region(pathSurface);
                //Draw surface border for HD result
                e.Graphics.DrawPath(penSurface, pathSurface);

                //Menu Border
                if (borderSize >= 1)
                    e.Graphics.DrawPath(penBorder, pathBorder);
            }
        }
        else //Normal contex menu
        {
            //Menu surface
            this.Region = new Region(rectSurface);
            //Menu border
            if (borderSize >= 1)
            {
                using (Pen penBorder = new Pen(borderColor, borderSize))
                {
                    penBorder.Alignment = PenAlignment.Inset;
                    e.Graphics.DrawRectangle(penBorder, 0, 0, this.Width - 1, this.Height - 1);
                }
            }
        }

    }

    //Overrides
    protected override void OnHandleCreated(EventArgs e)
    {
        base.OnHandleCreated(e);

        if (this.DesignMode == false)
        {
            //this.Parent.BackColorChanged += Parent_BackColorChanged;

            switch (SystrayTheme)
            {
                case WindowsTheme.Light:
                    {
                        menuItemTextColor = Color.Black;
                    }
                    break;
                case WindowsTheme.Dark:
                    {
                        menuItemTextColor = Color.White;
                    }
                    break;
                case WindowsTheme.HighContrast:
                    {
                        menuItemTextColor = Utility.ToDrawingColor(System.Windows.SystemColors.MenuTextColor);
                    }
                    break;
            }
            this.RenderMode = ToolStripRenderMode.Professional;
            this.Renderer = new MenuRenderer(isMainMenu, primaryColor, menuItemTextColor, MouseOverColor, MouseOverBorderColor, SystrayTheme);
            LoadMenuItemHeight();
        }
    }

    private void Parent_BackColorChanged(object sender, EventArgs e)
    {
        if (this.DesignMode)
            this.Invalidate();
    }
</code>```

Thanks in Advance. Any help will be appreciated.

答:
You can find the solution on this page: https://learn.microsoft.com/en-us/windows/apps/desktop/modernize/apply-rounded-corners

I also include the solution here just in case the external link gets deleted.

```<code>// The enum flag for DwmSetWindowAttribute's second parameter, which tells the function what attribute to set.
public enum DWMWINDOWATTRIBUTE
{
    DWMWA_WINDOW_CORNER_PREFERENCE = 33
}

// The DWM_WINDOW_CORNER_PREFERENCE enum for DwmSetWindowAttribute's third parameter, which tells the function
// what value of the enum to set.
public enum DWM_WINDOW_CORNER_PREFERENCE
{
   DWMWCP_DEFAULT      = 0,
   DWMWCP_DONOTROUND   = 1,
   DWMWCP_ROUND        = 2,
   DWMWCP_ROUNDSMALL   = 3
}

// Import dwmapi.dll and define DwmSetWindowAttribute in C# corresponding to the native function.
[DllImport("dwmapi.dll", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern long DwmSetWindowAttribute(IntPtr hwnd,
                                                 DWMWINDOWATTRIBUTE attribute,
                                                 ref DWM_WINDOW_CORNER_PREFERENCE pvAttribute,
                                                 uint cbAttribute);
</code>```

And to apply the rounded corners to the ContextMenuStrip:

```<code>ContextMenuStrip notifyIconMenu = new ContextMenuStrip();
...
var attribute = DWMWINDOWATTRIBUTE.DWMWA_WINDOW_CORNER_PREFERENCE;
var preference = DWM_WINDOW_CORNER_PREFERENCE.DWMWCP_ROUND;
DwmSetWindowAttribute(notifyIconMenu.Handle, attribute, ref preference, sizeof(uint));
</code>```

UPD
Here is the implementation of the submenu:

```<code>ToolStripMenuItem submenu = new ToolStripMenuItem("submenu");
notifyIconMenu.Items.Add(submenu);

ToolStripMenuItem submenuItem1 = new ToolStripMenuItem("submenu1");
submenu.DropDownItems.Add(submenuItem1);
DwmSetWindowAttribute(submenu.DropDown.Handle, attribute, ref preference, sizeof(uint));
</code>```

In case you want to go the proprietary implementation route for rounded corners, here's a method for creating "smooth" ones:

```<code>Graphics graphics = ...;
...
graphics.InterpolationMode = InterpolationMode.HighQualityBilinear;
graphics.CompositingQuality = CompositingQuality.HighQuality;
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
graphics.SmoothingMode = SmoothingMode.AntiAlias;
</code>```

Body:
In windows 11, I have found that almost every Systray Icon's Context Menu has a round corner.
As there is no Systray Menu for WPF application, I have used Window's form NotiIcon and ContextMenuStrip.
I have fully customized ToolStripProfessionalRenderer with ProfessionalColorTable to support dark mode
as per clients' requirements. Now I'm looking for rounding the corner. I was used "RoundedEdges = true;"
but not worked. I need to know exactly which method need to override to round the corner of ContextMenuStrip.

Here below is my renderer sample code.

   ///Menu Renderer
public class MenuRenderer : ToolStripProfessionalRenderer
{
    //Fields
    private Color primaryColor;
    private Color textColor;
    private int arrowThickness;
    private WindowsTheme systrayTheme;

    [Browsable(false)]
    public WindowsTheme SystrayTheme
    {
        get { return systrayTheme; }
        set { systrayTheme = value; }
    }

    //Constructor
    public MenuRenderer(bool isMainMenu, Color primaryColor, Color textColor, Color menuItemMouseOverColor, Color menuItemMouseOverBorderColor, WindowsTheme theme)
        : base(new MenuColorTable(isMainMenu, primaryColor, menuItemMouseOverColor, menuItemMouseOverBorderColor, theme))
    {
        RoundedEdges = true;

        this.primaryColor = primaryColor;
        this.systrayTheme = theme;

        if (isMainMenu)
        {
            arrowThickness = 2;
            if (textColor == Color.Empty) //Set Default Color
                this.textColor = Color.Gainsboro;
            else//Set custom text color
                this.textColor = textColor;
        }
        else
        {
            arrowThickness = 1;
            if (textColor == Color.Empty) //Set Default Color
                this.textColor = Color.DimGray;
            else//Set custom text color
                this.textColor = textColor;
        }
    }

    //Overrides
    protected override void OnRenderItemText(ToolStripItemTextRenderEventArgs e)
    {
        base.OnRenderItemText(e);
        e.Item.ForeColor = e.Item.Selected ? Color.White : textColor;
    }

    protected override void OnRenderArrow(ToolStripArrowRenderEventArgs e)
    {
        //Fields
        var graph = e.Graphics;
        var arrowSize = new Size(5, 10);
        var arrowColor = e.Item.Selected ? Color.White : primaryColor;
        var rect = new Rectangle(e.ArrowRectangle.Location.X, (e.ArrowRectangle.Height - arrowSize.Height) / 2,
            arrowSize.Width, arrowSize.Height);
        using (GraphicsPath path = new GraphicsPath())
        using (Pen pen = new Pen(arrowColor, arrowThickness))
        {
            //Drawing
            graph.SmoothingMode = SmoothingMode.AntiAlias;
            path.AddLine(rect.Left, rect.Top, rect.Right, rect.Top + rect.Height / 2);
            path.AddLine(rect.Right, rect.Top + rect.Height / 2, rect.Left, rect.Top + rect.Height);
            graph.DrawPath(pen, path);
        }
    }

    protected override void OnRenderGrip(ToolStripGripRenderEventArgs e)
    {
        Rectangle rectangle = new Rectangle(e.AffectedBounds.X, e.AffectedBounds.Y, e.AffectedBounds.Width, e.AffectedBounds.Height);
        GraphicsPath graphicsPath = RoundedRect(rectangle, 8);

        using (Pen pen = new Pen(Color.Green,5))
        {
            e.Graphics.DrawPath(pen, graphicsPath);
            //e.Graphics.FillPath(pen.Brush, graphicsPath);
        }
    }

    protected override void OnRenderToolStripPanelBackground(ToolStripPanelRenderEventArgs e)
    {
        //base.OnRenderToolStripPanelBackground(e);
        Rectangle rectangle = new Rectangle(e.ToolStripPanel.Location.X, e.ToolStripPanel.Location.Y,
            e.ToolStripPanel.ClientRectangle.Width, e.ToolStripPanel.ClientRectangle.Height);
        GraphicsPath graphicsPath = RoundedRect(rectangle, 8);

        using (Pen pen = new Pen(Color.Green, 5))
        {
            //e.Graphics.DrawPath(pen, graphicsPath);
            e.Graphics.FillPath(pen.Brush, graphicsPath);
        }
    }

    protected override void OnRenderStatusStripSizingGrip(ToolStripRenderEventArgs e)
    {
        //base.OnRenderStatusStripSizingGrip(e);
        Rectangle rectangle = new Rectangle(e.AffectedBounds.X, e.AffectedBounds.Y, e.AffectedBounds.Width, e.AffectedBounds.Height);
        GraphicsPath graphicsPath = RoundedRect(rectangle, 8);

        using (Pen pen = new Pen(Color.Green,5))
        {
            e.Graphics.DrawPath(pen, graphicsPath);
            //e.Graphics.FillPath(pen.Brush, graphicsPath);
        }
    }

    protected override void OnRenderToolStripBorder(ToolStripRenderEventArgs e)
    {
        //Fields
        //var graph = e.Graphics;
        //var borderZise = new Size(e.AffectedBounds.Width + 10, e.AffectedBounds.Height + 10);
        //var borderColor = Color.DeepPink;

        //var rect = new Rectangle(e.AffectedBounds.X, (e.AffectedBounds.Height - borderZise.Height) / 2,
        //    borderZise.Width, borderZise.Height);
        //using (GraphicsPath path = new GraphicsPath())
        //using (Pen pen = new Pen(borderColor, arrowThickness))
        //{
        //    //Drawing
        //    graph.SmoothingMode = SmoothingMode.AntiAlias;
        //    path.AddLine(rect.Left, rect.Top, rect.Right, rect.Top + rect.Height / 2);
        //    path.AddLine(rect.Right, rect.Top + rect.Height / 2, rect.Left, rect.Top + rect.Height);
        //    graph.DrawPath(pen, path);
        //}
        //DrawRoundedRectangle(e.Graphics, e.AffectedBounds.X, e.AffectedBounds.Y, e.AffectedBounds.Width - 5, e.AffectedBounds.Height, 15, Color.Red);

        //Rectangle rectangle = new Rectangle(e.AffectedBounds.X, e.AffectedBounds.Y, e.AffectedBounds.Width, e.AffectedBounds.Height);
        //GraphicsPath graphicsPath = RoundedRect(rectangle, 8);

        //using (Pen pen = new Pen(Color.Green, 2))
        //{
        //    //e.Graphics.DrawPath(pen, graphicsPath);
        //    e.Graphics.FillPath(pen.Brush, graphicsPath);
        //}
    }

    public GraphicsPath RoundedRect(Rectangle bounds, int radius)
    {
        int diameter = radius * 2;
        Size size = new Size(diameter, diameter);
        Rectangle arc = new Rectangle(bounds.Location, size);
        GraphicsPath path = new GraphicsPath();

        if (radius == 0)
        {
            path.AddRectangle(bounds);
            return path;
        }

        // top left arc
        path.AddArc(arc, 180, 90);

        // top right arc
        arc.X = bounds.Right - diameter;
        path.AddArc(arc, 270, 90);

        // bottom right arc
        arc.Y = bounds.Bottom - diameter;
        path.AddArc(arc, 0, 90);

        // bottom left arc
        arc.X = bounds.Left;
        path.AddArc(arc, 90, 90);

        path.CloseFigure();
        return path;
    }
}

////////Custom Menu
public class CustomContextMenu : ContextMenuStrip
{
    //Fields
    private bool isMainMenu;
    private int menuItemHeight = 20;
    private int menuItemWidth = 20;
    private Color menuItemTextColor = Color.Empty;
    private Color primaryColor = Color.Empty;
    private Color MouseOverColor = Color.Empty;
    private Color MouseOverBorderColor = Color.Empty;
    private WindowsTheme systrayTheme = WindowsTheme.Light;
    private Bitmap menuItemHeaderSize;

    //Constructor
    public CustomContextMenu()
    {

    }

    //Properties
    [Browsable(false)]
    public bool IsMainMenu
    {
        get { return isMainMenu; }
        set { isMainMenu = value; }
    }

    [Browsable(false)]
    public int MenuItemHeight
    {
        get { return menuItemHeight; }
        set { menuItemHeight = value; }
    }

    [Browsable(false)]
    public int MenuItemWidth
    {
        get { return menuItemWidth; }
        set { menuItemWidth = value; }
    }

    [Browsable(false)]
    public Color MenuItemTextColor
    {
        get { return menuItemTextColor; }
        set { menuItemTextColor = value; }
    }

    [Browsable(false)]
    public Color PrimaryColor
    {
        get { return primaryColor; }
        set { primaryColor = value; }
    }

    [Browsable(false)]
    public Color MenuItemMouseOverColor
    {
        get { return MouseOverColor; }
        set { MouseOverColor = value; }
    }

    [Browsable(false)]
    public Color MenuItemMouseOverBorderColor
    {
        get { return MouseOverBorderColor; }
        set { MouseOverBorderColor = value; }
    }

    [Browsable(false)]
    public WindowsTheme SystrayTheme
    {
        get { return systrayTheme; }
        set { systrayTheme = value; }
    }

    //Private methods
    private void LoadMenuItemHeight()
    {
        if (isMainMenu)
            menuItemHeaderSize = new Bitmap(menuItemWidth, menuItemHeight);
        else menuItemHeaderSize = new Bitmap(menuItemWidth-5, menuItemHeight);

        foreach (Forms.ToolStripMenuItem menuItemL1 in this.Items)
        {
            menuItemL1.ImageScaling = ToolStripItemImageScaling.None;
            if (menuItemL1.Image == null) menuItemL1.Image = menuItemHeaderSize;

            foreach (Forms.ToolStripMenuItem menuItemL2 in menuItemL1.DropDownItems)
            {
                menuItemL2.ImageScaling = ToolStripItemImageScaling.None;
                if (menuItemL2.Image == null) menuItemL2.Image = menuItemHeaderSize;

                foreach (Forms.ToolStripMenuItem menuItemL3 in menuItemL2.DropDownItems)
                {
                    menuItemL3.ImageScaling = ToolStripItemImageScaling.None;
                    if (menuItemL3.Image == null) menuItemL3.Image = menuItemHeaderSize;

                    foreach (Forms.ToolStripMenuItem menuItemL4 in menuItemL3.DropDownItems)
                    {
                        menuItemL4.ImageScaling = ToolStripItemImageScaling.None;
                        if (menuItemL4.Image == null) menuItemL4.Image = menuItemHeaderSize;
                        ///Level 5++
                    }
                }
            }
        }
    }

    //Overrides
    protected override void OnHandleCreated(EventArgs e)
    {
        base.OnHandleCreated(e);
        if (this.DesignMode == false)
        {
            switch (SystrayTheme)
            {
                case WindowsTheme.Light:
                    {
                        menuItemTextColor = Color.Black;
                    }
                    break;
                case WindowsTheme.Dark:
                    {
                        menuItemTextColor = Color.White;
                    }
                    break;
                case WindowsTheme.HighContrast:
                    {
                        menuItemTextColor = Utility.ToDrawingColor(System.Windows.SystemColors.MenuTextColor);
                    }
                    break;
            }

            this.Renderer = new MenuRenderer(isMainMenu, primaryColor, menuItemTextColor, MouseOverColor, MouseOverBorderColor, SystrayTheme);
            LoadMenuItemHeight();
        }
    }
 }

Update:

Recently I was tried to override OnPaint() method. But the round corner is not smooth and also sub-menu is not rounded.

    private GraphicsPath GetGraphicsPath(RectangleF rect,float radious)
    {
        GraphicsPath path = new GraphicsPath();
        path.StartFigure();
        path.AddArc(rect.X, rect.Y, radious, radious, 180, 90);
        path.AddArc(rect.Width - radious, rect.Y, radious, radious, 270, 90);
        path.AddArc(rect.Width - radious, rect.Height - radious, radious, radious, 0, 90);
        path.AddArc(rect.X, rect.Height - radious, radious, radious, 90, 90);

        path.CloseFigure();

        return path;
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);
        e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;

        RectangleF rectSurface = new RectangleF(0, 0, this.Width, this.Height);
        RectangleF rectBorder = new RectangleF(1, 1, this.Width - 0.8F, this.Height - 1);

        if (borderRadius > 2) //Rounder
        {
            using (GraphicsPath pathSurface = GetGraphicsPath(rectSurface, borderRadius))
            using (GraphicsPath pathBorder = GetGraphicsPath(rectBorder, borderRadius - 1F))
            using (Pen penSurface = new Pen(this.BackColor, 2))
            using (Pen penBorder = new Pen(borderColor, borderSize))
            {
                penBorder.Alignment = PenAlignment.Inset;
                //Menu surface
                this.Region = new Region(pathSurface);
                //Draw surface border for HD result
                e.Graphics.DrawPath(penSurface, pathSurface);

                //Menu Border
                if (borderSize >= 1)
                    e.Graphics.DrawPath(penBorder, pathBorder);
            }
        }
        else //Normal contex menu
        {
            //Menu surface
            this.Region = new Region(rectSurface);
            //Menu border
            if (borderSize >= 1)
            {
                using (Pen penBorder = new Pen(borderColor, borderSize))
                {
                    penBorder.Alignment = PenAlignment.Inset;
                    e.Graphics.DrawRectangle(penBorder, 0, 0, this.Width - 1, this.Height - 1);
                }
            }
        }

    }

    //Overrides
    protected override void OnHandleCreated(EventArgs e)
    {
        base.OnHandleCreated(e);

        if (this.DesignMode == false)
        {
            //this.Parent.BackColorChanged += Parent_BackColorChanged;

            switch (SystrayTheme)
            {
                case WindowsTheme.Light:
                    {
                        menuItemTextColor = Color.Black;
                    }
                    break;
                case WindowsTheme.Dark:
                    {
                        menuItemTextColor = Color.White;
                    }
                    break;
                case WindowsTheme.HighContrast:
                    {
                        menuItemTextColor = Utility.ToDrawingColor(System.Windows.SystemColors.MenuTextColor);
                    }
                    break;
            }
            this.RenderMode = ToolStripRenderMode.Professional;
            this.Renderer = new MenuRenderer(isMainMenu, primaryColor, menuItemTextColor, MouseOverColor, MouseOverBorderColor, SystrayTheme);
            LoadMenuItemHeight();
        }
    }

    private void Parent_BackColorChanged(object sender, EventArgs e)
    {
        if (this.DesignMode)
            this.Invalidate();
    }

Thanks in Advance. Any help will be appreciated.

Body:
You can find the solution on this page: https://learn.microsoft.com/en-us/windows/apps/desktop/modernize/apply-rounded-corners

I also include the solution here just in case the external link gets deleted.

// The enum flag for DwmSetWindowAttribute's second parameter, which tells the function what attribute to set.
public enum DWMWINDOWATTRIBUTE
{
    DWMWA_WINDOW_CORNER_PREFERENCE = 33
}

// The DWM_WINDOW_CORNER_PREFERENCE enum for DwmSetWindowAttribute's third parameter, which tells the function
// what value of the enum to set.
public enum DWM_WINDOW_CORNER_PREFERENCE
{
   DWMWCP_DEFAULT      = 0,
   DWMWCP_DONOTROUND   = 1,
   DWMWCP_ROUND        = 2,
   DWMWCP_ROUNDSMALL   = 3
}

// Import dwmapi.dll and define DwmSetWindowAttribute in C# corresponding to the native function.
[DllImport("dwmapi.dll", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern long DwmSetWindowAttribute(IntPtr hwnd,
                                                 DWMWINDOWATTRIBUTE attribute,
                                                 ref DWM_WINDOW_CORNER_PREFERENCE pvAttribute,
                                                 uint cbAttribute);

And to apply the rounded corners to the ContextMenuStrip:

ContextMenuStrip notifyIconMenu = new ContextMenuStrip();
...
var attribute = DWMWINDOWATTRIBUTE.DWMWA_WINDOW_CORNER_PREFERENCE;
var preference = DWM_WINDOW_CORNER_PREFERENCE.DWMWCP_ROUND;
DwmSetWindowAttribute(notifyIconMenu.Handle, attribute, ref preference, sizeof(uint));

UPD
Here is the implementation of the submenu:

ToolStripMenuItem submenu = new ToolStripMenuItem("submenu");
notifyIconMenu.Items.Add(submenu);

ToolStripMenuItem submenuItem1 = new ToolStripMenuItem("submenu1");
submenu.DropDownItems.Add(submenuItem1);
DwmSetWindowAttribute(submenu.DropDown.Handle, attribute, ref preference, sizeof(uint));

In case you want to go the proprietary implementation route for rounded corners, here's a method for creating "smooth" ones:

Graphics graphics = ...;
...
graphics.InterpolationMode = InterpolationMode.HighQualityBilinear;
graphics.CompositingQuality = CompositingQuality.HighQuality;
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
graphics.SmoothingMode = SmoothingMode.AntiAlias;


来源: stackexchange

问:
How to fire keyboard events in Javascript using onClick?
I have an existing function that gets called when KeyD is pressed.

I want to trigger an KeyD event (without actually pressing keyD on keyboard) as soon as I click on some button.

Is it possible in Javascript?

答:
you can use the onkeypress() function from javascript that will trigger on every keyPress.
</p>

ContentLicense: CC BY-SA 4.0


问:
Why list items image not show in jetpack compose project?
I am try to learning jetpack compose, and I have list items with name and image, my project working and no problem for list name , but user images are not showing in the emulator. I do not know what I missed. Is there any solution?

Model:

```<code>   data class Data(
    var name: String,
    var image: String)
</code>```

Screen:

```<code>@Composable
fun DataScreen() {

    val listOfData = listOf(
        Data("name1", "image1"),
        Data("name2", "image2"),
        Data("name3",  "image3"),)

    Column(
        horizontalAlignment = Alignment.CenterHorizontally,
        modifier = Modifier
            .fillMaxSize()
            .background(Color.White)

    ) {

        LazyColumn(
            modifier = Modifier
        ) {

            items(listOfData.size) { index ->
                DataListItem(listOfData[index])
            }}}}

</code>```

Item:

```<code>@Composable
fun DataListItem(data: Data) {

    val context = LocalContext.current
    val painter = rememberImagePainter(
        data = data.image
    )
    Column(
        modifier = Modifier.padding(5.dp)
    ) {

        Row(
            modifier = Modifier
                .fillMaxWidth()
                .padding(5.dp)

        ) {

            Image(
                painter = painter,
                contentDescription = null,
                contentScale = ContentScale.Crop,
                modifier = Modifier
                    .size(32.dp)
                    .clip(CircleShape))

                Text(
                    text = data.name,
                    fontSize = 12.sp,

                )}}}

</code>```

答:
All I see is a string for your image. A painter can't display an image from just a string. You also don't need to use state management for the painter since you've included the painter in a Data object that retains the state:

This code has been tested:

data class Data(
    var name: String,
    var painter: Painter
)

@Composable
fun DataScreen() {

    val listOfData = listOf(
        Data("name1", painterResource(R.drawable.cat_1)),
        Data("name2", painterResource(R.drawable.cat_2))
    )

    Column(
        horizontalAlignment = Alignment.CenterHorizontally,
        modifier = Modifier
            .fillMaxSize()
            .background(Color.White)

    ) {

        LazyColumn(
            modifier = Modifier.fillMaxSize()
        ) {

            items(listOfData.size) { index ->
                DataListItem(listOfData[index])
            }
        }
    }
}

@Composable
fun DataListItem(data: Data) {

    Column(
        modifier = Modifier
            .fillMaxWidth()
            .padding(5.dp)
    ) {

        Row(
            modifier = Modifier
                .fillMaxWidth()
                .padding(5.dp)

        ) {

            Image(
                painter = data.painter,
                contentDescription = null,
                contentScale = ContentScale.Crop,
                modifier = Modifier
                    .size(32.dp)
                    .clip(CircleShape)
            )

            Text(
                text = data.name,
                fontSize = 12.sp,

                )
        }
    }
}
```

Body:
I am try to learning jetpack compose, and I have list items with name and image, my project working and no problem for list name , but user images are not showing in the emulator. I do not know what I missed. Is there any solution?

Model:

   data class Data(
    var name: String,
    var image: String)

Screen:

@Composable
fun DataScreen() {

    val listOfData = listOf(
        Data("name1", "image1"),
        Data("name2", "image2"),
        Data("name3",  "image3"),)

    Column(
        horizontalAlignment = Alignment.CenterHorizontally,
        modifier = Modifier
            .fillMaxSize()
            .background(Color.White)

    ) {

        LazyColumn(
            modifier = Modifier
        ) {

            items(listOfData.size) { index ->
                DataListItem(listOfData[index])
            }}}}

Item:

@Composable
fun DataListItem(data: Data) {

    val context = LocalContext.current
    val painter = rememberImagePainter(
        data = data.image
    )
    Column(
        modifier = Modifier.padding(5.dp)
    ) {

        Row(
            modifier = Modifier
                .fillMaxWidth()
                .padding(5.dp)

        ) {

            Image(
                painter = painter,
                contentDescription = null,
                contentScale = ContentScale.Crop,
                modifier = Modifier
                    .size(32.dp)
                    .clip(CircleShape))

                Text(
                    text = data.name,
                    fontSize = 12.sp,

                )}}}


问:
Give 404 response on DELETE in restful Spring Boot Reactive Controller
I am fairly new to Java and Spring Boot (coming from TypeScript) and
experimenting with a small restful CRUD Controller using the
reactive Spring Boot API.

There are many tutorials and examples out there but they all lack
proper response statuses, e.g. giving a 404 on DELETE when the
resource doesn't exist.

What I like to achieve is a DELETE handler which

returns "204 No Content" if the resource existed and was deleted successfully

returns "404 Not found" if the resource doesn't exist

A simple "I don't care about HTTP status" DELETE handler
looks like this:

  @DeleteMapping("/{id}")
  public Mono<Void> deletePet(@PathVariable String id) {
    return petRepository.deleteById(id);
  }
```
<p>This always gives status 200, even when there is no Pet for this ID.</p>
<p>I tried to use <code>petRepository.findById(id)</code> and <code>.defaultIfEmpty()</code>
in several ways to catch the 404 case, but without luck. E.g. with
this implementation I am getting always 204:</p>
<pre class="lang-java prettyprint-override"><code>  @DeleteMapping("/{id}")
  public Mono<ResponseEntity<Void>> deletePet(@PathVariable String id) {
    return petRepository.findById(id)
      .map(pet1 -> new ResponseEntity<Void>(HttpStatus.NO_CONTENT))
      .defaultIfEmpty(new ResponseEntity<Void>(HttpStatus.NOT_FOUND))
      .flatMap(res -> {
        return petRepository.deleteById(id)
          .map(v -> new ResponseEntity<Void>(HttpStatus.NO_CONTENT));
      });
  }
</code>```

I think I understand why this isn't working, because after the .defaultIfEmpty()
the Mono isn't empty anymore and the .flatMap will have something to work
on (the 404 response) so the deleteById() is executed. This returns an (obviously)
non empty Mono as well, so the status turns into NO_CONTENT again.

But all my (many) attempts to change this failed so I hope anyone has the right
solution for this problem.

Thanks! :)

答:
When findById returns an empty Mono, the code below will not executed either map or flatMap and will only return the value from defaultIfEmpty

 @DeleteMapping("/{id}")
  public Mono<ResponseEntity<Void>> deletePet(@PathVariable String id) {
    return petRepository.findById(id)
      .map(pet1 -> new ResponseEntity<Void>(HttpStatus.NO_CONTENT))
      .flatMap(res -> {
        return petRepository.deleteById(id)
          .map(v -> new ResponseEntity<Void>(HttpStatus.NO_CONTENT));
      })
      .defaultIfEmpty(new ResponseEntity<Void>(HttpStatus.NOT_FOUND));
  }
```

Also, your understanding as to why this happens in your code snippet is correct.

Body:
I am fairly new to Java and Spring Boot (coming from TypeScript) and
experimenting with a small restful CRUD Controller using the
reactive Spring Boot API.

There are many tutorials and examples out there but they all lack
proper response statuses, e.g. giving a 404 on DELETE when the
resource doesn't exist.

What I like to achieve is a DELETE handler which

returns "204 No Content" if the resource existed and was deleted successfully

returns "404 Not found" if the resource doesn't exist

A simple "I don't care about HTTP status" DELETE handler
looks like this:

  @DeleteMapping("/{id}")
  public Mono<Void> deletePet(@PathVariable String id) {
    return petRepository.deleteById(id);
  }

This always gives status 200, even when there is no Pet for this ID.

I tried to use petRepository.findById(id) and .defaultIfEmpty()
in several ways to catch the 404 case, but without luck. E.g. with
this implementation I am getting always 204:

  @DeleteMapping("/{id}")
  public Mono<ResponseEntity<Void>> deletePet(@PathVariable String id) {
    return petRepository.findById(id)
      .map(pet1 -> new ResponseEntity<Void>(HttpStatus.NO_CONTENT))
      .defaultIfEmpty(new ResponseEntity<Void>(HttpStatus.NOT_FOUND))
      .flatMap(res -> {
        return petRepository.deleteById(id)
          .map(v -> new ResponseEntity<Void>(HttpStatus.NO_CONTENT));
      });
  }

I think I understand why this isn't working, because after the .defaultIfEmpty()
the Mono isn't empty anymore and the .flatMap will have something to work
on (the 404 response) so the deleteById() is executed. This returns an (obviously)
non empty Mono as well, so the status turns into NO_CONTENT again.

But all my (many) attempts to change this failed so I hope anyone has the right
solution for this problem.

Thanks! :)

Body:
When findById returns an empty Mono, the code below will not executed either map or flatMap and will only return the value from defaultIfEmpty

 @DeleteMapping("/{id}")
  public Mono<ResponseEntity<Void>> deletePet(@PathVariable String id) {
    return petRepository.findById(id)
      .map(pet1 -> new ResponseEntity<Void>(HttpStatus.NO_CONTENT))
      .flatMap(res -> {
        return petRepository.deleteById(id)
          .map(v -> new ResponseEntity<Void>(HttpStatus.NO_CONTENT));
      })
      .defaultIfEmpty(new ResponseEntity<Void>(HttpStatus.NOT_FOUND));
  }

Also, your understanding as to why this happens in your code snippet is correct.


问:
Find first file in directory with Java
I have some sort of batch program that should pick up a file from a directory and process it.

Since this program is supposed to:

run on JDK 5,

be small (no external libraries)

and fast! (with a bang)

...what is the best way to only pick one file from the directory - without using File.list() (might be hundreds of files)?

答:
In Java 7 you could use a DirectoryStream, but in Java 5, the only ways to get directory entries are list() and listFiles().

Note that listing a directory with hundreds of files is not ideal but still probably no big deal compared to processing one of the files. But it would probably start to be problematic once the directory contains many thousands of files.

ContentLicense: CC BY-SA 3.0

Title: Find first file in directory with Java


问:
Google api auth2 signOut not working
First off, I am following this guide https://developers.google.com/identity/sign-in/web/ and this reference https://developers.google.com/identity/sign-in/web/reference.

But instead of having a callback declared in window, I used gapi.signin2.render function to render the button and attach a handler to it in my Angular controller.

Logging in works just fine, problem is, when I try to log out by calling gapi.auth2.getAuthInstance().signOut(), it just doesn't do it.

I noticed that sessionStorage for accounts.google.com is still there, and because of that Google automatically signs me back in when I render the button again on the login screen.

I tried seeing what happens after signOut() is complete:

```<code>gapi.auth2.getAuthInstance().signOut().then(function() {
    console.log(gapi.auth2.getAuthInstance().isSignedIn.get());
    // prints 'true'
});
</code>```

I also tried calling disconnect() instead of signOut(), knowing that it will revoke access, and it does remove token from the sessionStorage, but user session is still there. It is only gone once I reload the page.

Here is my complete code:

```<code>$scope.logout = function() {
    //...
    gapi.auth2.getAuthInstance().signOut().then(function() {
      console.log(gapi.auth2.getAuthInstance().isSignedIn);
    });
};

$scope.processAuth = function(authResult) {
  console.log("success");
  if(authResult.getAuthResponse().id_token) {
    // backend calls
  }
};

$scope.renderSignInButton = function() {
  console.log(gapi.auth2);
  gapi.signin2.render('signInButton',
    {
      'onsuccess': $scope.processAuth, // Function handling the callback.
      'onfailure': $scope.signinFailed, // Function handling the callback.
      'clientid': 'asdasdasd.apps.googleusercontent.com',
      'scope': 'https://www.googleapis.com/auth/userinfo.email',
      'cookiepolicy': 'single_host_origin'
    }
  );
};

$scope.renderSignInButton();
</code>```

答:
for me the problem was only in chrome because of the one profile mode.
profile mode means that you only connected to one account, in order to see the list of accounts you need to be connected to multiple accounts, but with the profile mode ON, you only connected to one account, so there is no list to show - there is only that one account.

do a test on firefox whene you connected to at list 2 google accounts, and you will see the list or exist of profile mode in chrome(but i have no idea how to do that, i stack in profile mode in chrome for the moment)

Title: Google api auth2 signOut not working

Body:
First off, I am following this guide https://developers.google.com/identity/sign-in/web/ and this reference https://developers.google.com/identity/sign-in/web/reference.

But instead of having a callback declared in window, I used gapi.signin2.render function to render the button and attach a handler to it in my Angular controller.

Logging in works just fine, problem is, when I try to log out by calling gapi.auth2.getAuthInstance().signOut(), it just doesn't do it.

I noticed that sessionStorage for accounts.google.com is still there, and because of that Google automatically signs me back in when I render the button again on the login screen.

I tried seeing what happens after signOut() is complete:

gapi.auth2.getAuthInstance().signOut().then(function() {
    console.log(gapi.auth2.getAuthInstance().isSignedIn.get());
    // prints 'true'
});

I also tried calling disconnect() instead of signOut(), knowing that it will revoke access, and it does remove token from the sessionStorage, but user session is still there. It is only gone once I reload the page.

Here is my complete code:

$scope.logout = function() {
    //...
    gapi.auth2.getAuthInstance().signOut().then(function() {
      console.log(gapi.auth2.getAuthInstance().isSignedIn);
    });
};

$scope.processAuth = function(authResult) {
  console.log("success");
  if(authResult.getAuthResponse().id_token) {
    // backend calls
  }
};

$scope.renderSignInButton = function() {
  console.log(gapi.auth2);
  gapi.signin2.render('signInButton',
    {
      'onsuccess': $scope.processAuth, // Function handling the callback.
      'onfailure': $scope.signinFailed, // Function handling the callback.
      'clientid': 'asdasdasd.apps.googleusercontent.com',
      'scope': 'https://www.googleapis.com/auth/userinfo.email',
      'cookiepolicy': 'single_host_origin'
    }
  );
};

$scope.renderSignInButton();


问:
Why can't I get two lists from one list comprehension?
So I have an array of the following form:

```<code>[(1, u'first_type', u'data_gid_1'),
 (2, u'first_type', u'data_gid_2'),
 (3, u'first_type', u'data_gid_3'),
 (4, u'first_type', u'data_gid_4')]
</code>```

Now I want to extract the first and the last element of each inside list into separate lists. So if I do:

```<code>>>> ids = [dat[0] for dat in all_data]
>>> gds = [dat[2] for dat in all_data]
</code>```

This works as I expect it to. However I was trying to merge these two into one call, something like:

```<code> (ids, gds) = [(dat[0], dat[2]) for dat in all_data]
</code>```

This however fails with an:
     ValueError: too many values to unpack

So could anyone explain why this is happening and if what I am trying to do is even possible.

Regards,
Bogdan

答:
It doesn't work because the length of [(dat[0], dat[2]) for dat in all_data] is the same as the lenght of all_data, which is not the same length as the tuple (ids, gds).

Try this instead:

```<code>(ids, gds) = zip(*[(dat[0], dat[2]) for dat in all_data])
</code>```

or even shorter:

```<code>(ids, gds) = zip(*all_data)[::2]
</code>```

As noted in another answer, ids and gds will now be tuples, so if you need lists, do like this:

```<code>(ids, gds) = map(list, zip(*all_data)[::2])
</code>```

The zip(*something) is a rather frequently occuring idiom in python. If you look at a list of lists as a matrix, i.e.

```<code>l = [[1, 2, 3],
     [4, 5, 6]]
</code>```

Then zip(*l) transposes that matrix:

```<code>zip(*l) == [(1, 4),
            (2, 5),
            (3, 6)]
</code>```

The * works like this: some_func(*some_list) unpacks some_list so that the function is in effect called with the elements of some_list as arguments. So zip(*l) is the same as zip([1, 2, 3], [4, 5, 6]). Here's the relevant part of the python tutorial.

zip acts like a zipper, hence the name, so it returns a list with these elements: a tuple of all the first elements of the given arguments, followed by a tuple of all the second elements, etc.

Body:
So I have an array of the following form:

[(1, u'first_type', u'data_gid_1'),
 (2, u'first_type', u'data_gid_2'),
 (3, u'first_type', u'data_gid_3'),
 (4, u'first_type', u'data_gid_4')]

Now I want to extract the first and the last element of each inside list into separate lists. So if I do:

>>> ids = [dat[0] for dat in all_data]
>>> gds = [dat[2] for dat in all_data]

This works as I expect it to. However I was trying to merge these two into one call, something like:

 (ids, gds) = [(dat[0], dat[2]) for dat in all_data]

This however fails with an:
     ValueError: too many values to unpack

So could anyone explain why this is happening and if what I am trying to do is even possible.

Regards,
Bogdan

Body:
It doesn't work because the length of [(dat[0], dat[2]) for dat in all_data] is the same as the lenght of all_data, which is not the same length as the tuple (ids, gds).

Try this instead:

(ids, gds) = zip(*[(dat[0], dat[2]) for dat in all_data])

or even shorter:

(ids, gds) = zip(*all_data)[::2]

As noted in another answer, ids and gds will now be tuples, so if you need lists, do like this:

(ids, gds) = map(list, zip(*all_data)[::2])

The zip(*something) is a rather frequently occuring idiom in python. If you look at a list of lists as a matrix, i.e.

l = [[1, 2, 3],
     [4, 5, 6]]

Then zip(*l) transposes that matrix:

zip(*l) == [(1, 4),
            (2, 5),
            (3, 6)]

The * works like this: some_func(*some_list) unpacks some_list so that the function is in effect called with the elements of some_list as arguments. So zip(*l) is the same as zip([1, 2, 3], [4, 5, 6]). Here's the relevant part of the python tutorial.

zip acts like a zipper, hence the name, so it returns a list with these elements: a tuple of all the first elements of the given arguments, followed by a tuple of all the second elements, etc.


问:
Azure Functions Runtime is unreachable - Works published locally - Fails on CI/CD Deployment (Q&A)
I have an Azure Function (not in a container).

When I publish it to Azure locally, it's fine.

When I publish it from Azure Devops, the deployment succeeds, but the Function wont run. Error 'Azure functions runtime is unreachable':

I've tried looking in the Log Stream, but this gives the error:

System.Private.CoreLib: Could not load file or assembly '{myAppName},
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.

I've looked at documents such as this troubleshooting guide, but that's not fixing it.

答:
When publishing locally, the standard publish format is 'Portable'. This is not precompiled, so the Functions App will compile it when starting up the app.

However, when publishing from CI/CD, I was compiling as part of the publish, using the following command:

```<code>dotnet publish projectName --framework $framework -r win-x64 -c Release
</code>```

Obviously, this is an x64 build.

I checked the App Service Configuration, and it was set to x86.

Changing it to x64 fixed the problem when deploying from DevOps.

I then also changed the local publish to x64, just to save compile time on startup.

Body:
When publishing locally, the standard publish format is 'Portable'. This is not precompiled, so the Functions App will compile it when starting up the app.

However, when publishing from CI/CD, I was compiling as part of the publish, using the following command:

dotnet publish projectName --framework $framework -r win-x64 -c Release

Obviously, this is an x64 build.

I checked the App Service Configuration, and it was set to x86.

Changing it to x64 fixed the problem when deploying from DevOps.

I then also changed the local publish to x64, just to save compile time on startup.


问:
How to update a chatMessage on quickblox android
Hi so I've just started using quickblox for android and I find it confusing that when updating a chatMesage I'm only limited to editing the text. Here is the code provided:

```<code>QBMessageUpdateBuilder messageUpdateBuilder = new QBMessageUpdateBuilder();
messageUpdateBuilder.updateText("Updated message body string");

// If you want to mark message as Delivered or Read on the server
//messageUpdateBuilder.markDelivered();
//messageUpdateBuilder.markRead();

QBRestChatService.updateMessage(message.getId(), message.getDialogId(), messageUpdateBuilder).performAsync(new QBEntityCallback<Void>() {
@Override
public void onSuccess(Void aVoid, Bundle bundle) {

}

@Override
public void onError(QBResponseException e) {

}
});
</code>```

I however have properties that I had set when creating the message using chatmessage.setProperty("myproperty", value) and I would like to update this at a later time yet I have found no method to facilitate this. Could there be a hack for doing so? Any help is appreciated

答:
Hello mr Nikolay Zolotarov,

I think you are wrong, SDK has update message method https://docs.quickblox.com/docs/android-chat-messaging#update-message but you can't update custom parameters

Body:
Hi so I've just started using quickblox for android and I find it confusing that when updating a chatMesage I'm only limited to editing the text. Here is the code provided:

QBMessageUpdateBuilder messageUpdateBuilder = new QBMessageUpdateBuilder();
messageUpdateBuilder.updateText("Updated message body string");

// If you want to mark message as Delivered or Read on the server
//messageUpdateBuilder.markDelivered();
//messageUpdateBuilder.markRead();

QBRestChatService.updateMessage(message.getId(), message.getDialogId(), messageUpdateBuilder).performAsync(new QBEntityCallback<Void>() {
@Override
public void onSuccess(Void aVoid, Bundle bundle) {

}

@Override
public void onError(QBResponseException e) {

}
});

I however have properties that I had set when creating the message using chatmessage.setProperty("myproperty", value) and I would like to update this at a later time yet I have found no method to facilitate this. Could there be a hack for doing so? Any help is appreciated


问:
Intellij Java Warning "Times" and "Lucida Bright" fonts are not available
I'm using Java version 8 update 301 on intelliJ IDEA CE on Mac OS Big Sur and get the error:

Warning: the fonts "Times" and "Lucida Bright" are not available for the Java logical font "Serif", which may have unexpected appearance or behavior. Re-enable the "Times" font to remove this warning.

Any idea how to re-enable the times font?

答:
The "Times" font is not available in macOS 12 Monterey. You can find it online and install it.

Or better, update Java to a more recent version; this change in macOS has been taken into account in Java, see JDK-8273358.


问:
Setting type to be equal to keys of an Object
I have an initial state object i.e.

```<code>
interface IInitialState {
  prop1: string;
  prop2: string;
  prop3: string;
  prop4: Array<number>;
}

const INITIAL_STATE: IInitialState = {
  prop1: '',
  prop2: '',
  prop3: '',
  prop4: [],
};
</code>```

Now I have declared another type as

```<code>type FieldType =
 | 'prop1'
 | 'prop2'
 | 'prop3'
 | 'prop4'

</code>```

Is there any elegant way to define FieldType such that it accepts only keys of INITIAL_STATE object instead of having me write it out as it's currently?

答:
Does this work for you?</p>
```<code>const INITIAL_STATE = {
    prop1: '',
    prop2: '',
    prop3: '',
    prop4: [],
}
type FieldType = keyof typeof INITIAL_STATE // gives "prop1" | "prop2" | "prop3" | "prop4"
</code>```

Body:
I have an initial state object i.e.

interface IInitialState {
  prop1: string;
  prop2: string;
  prop3: string;
  prop4: Array<number>;
}

const INITIAL_STATE: IInitialState = {
  prop1: '',
  prop2: '',
  prop3: '',
  prop4: [],
};

Now I have declared another type as

type FieldType =
 | 'prop1'
 | 'prop2'
 | 'prop3'
 | 'prop4'

Is there any elegant way to define FieldType such that it accepts only keys of INITIAL_STATE object instead of having me write it out as it's currently?

Body:
Does this work for you?

const INITIAL_STATE = {
    prop1: '',
    prop2: '',
    prop3: '',
    prop4: [],
}
type FieldType = keyof typeof INITIAL_STATE // gives "prop1" | "prop2" | "prop3" | "prop4"


问:
DataContext. Is there a single method where I can add an extra WHERE?
So basically I have an application that works with just one user, but I'd like to make it multi-user. This would involve me logging a user in, and keeping the user ID in session, plus adding a user id column to my database tables. no biggy.

I'd like to change my dbml, or use it's partial, so that any query I throw through it also gets

```<code>.WHERE(user=>user.id=MYPARAM)
</code>```

added to it, to return just records for the logged in user.

Is there a quick win to be had? A single place where I can specify this in the .dbml?

答:
I am not sure if there is something like that.

If there isn't, you can expose already filtered properties for all the tables in the partial class. You would then receive the user id as a parameter to the data context.

You can combine that with a dynamic expression so that those properties are as simple as possible to define.

OwnerDisplayName: jdee

ContentLicense: CC BY-SA 2.5

Body:
So basically I have an application that works with just one user, but I'd like to make it multi-user. This would involve me logging a user in, and keeping the user ID in session, plus adding a user id column to my database tables. no biggy.

I'd like to change my dbml, or use it's partial, so that any query I throw through it also gets

.WHERE(user=>user.id=MYPARAM)

added to it, to return just records for the logged in user.

Is there a quick win to be had? A single place where I can specify this in the .dbml?

LastEditorDisplayName: jdee

OwnerDisplayName: Freddy Rios


问:
Passing current page id to a link_to (Ruby/ Rails)
Apologies if this seems a bit vague.

Basically I have a page which loads content based on id. I'm trying to put links withing it like this

```<code><%= link_to 'mypage', {:action => 'mypageload', :id => '1'},{:class=>'mypages'}%>
</code>```

What I'd like to do is pass the id of the current page into this link.

So something like

```<code>:id => 'params[:id]'
</code>```

Is there a way to do this?

答: Remove the single quotes: :id => params[:id]

Body:
Apologies if this seems a bit vague.

Basically I have a page which loads content based on id. I'm trying to put links withing it like this

<%= link_to 'mypage', {:action => 'mypageload', :id => '1'},{:class=>'mypages'}%>

What I'd like to do is pass the id of the current page into this link.

So something like

:id => 'params[:id]'

Is there a way to do this?


问:
brew services. Cant start service. get "Bootstrap failed: 5: Input/output error"
running brew services start mongodb-community which yields:

```<code>Bootstrap failed: 5: Input/output error
Error: Failure while executing; `/bin/launchctl bootstrap gui/501 /Users/<myUserName>/Library/LaunchAgents/homebrew.mxcl.mongodb-community.plist` exited with 5.
</code>```

when I run launchctl load -w /Users/<myUserName>/Library/LaunchAgents/homebrew.mxcl.mongodb-community.plist

yields

Load failed: 5: Input/output error

I recently upgraded macOs to BigSur 11.5.2.

Ive uninstall and reinstalled homebrew and xcode.

答:
I faced a similar problem with postgresql 11 and restarting the service did not help. The issue arose when my MacBook restarted abruptly.

After checking the ports and trying out all the possible solutions, I decided to look into the logs.

```<code>tail -n 100 /usr/local/var/log/postgresql@11.log
</code>```

This gave me the last 100 lines of the log where I found this:

```<code>FATAL:  lock file "postmaster.pid" already exists
HINT:  Is another postmaster (PID 479) running in data directory "/usr/local/var/postgresql@11"?
</code>```

Clearly, the issue was with postmaster.pid so I deleted it:

```<code>rm /usr/local/var/postgresql@11/postmaster.pid
</code>```

Started the postgres service again:

```<code>brew services start postgresql@11
</code>```

and voila! It worked.

Body:
running brew services start mongodb-community which yields:

Bootstrap failed: 5: Input/output error
Error: Failure while executing; `/bin/launchctl bootstrap gui/501 /Users/<myUserName>/Library/LaunchAgents/homebrew.mxcl.mongodb-community.plist` exited with 5.

when I run launchctl load -w /Users/<myUserName>/Library/LaunchAgents/homebrew.mxcl.mongodb-community.plist

yields

Load failed: 5: Input/output error

I recently upgraded macOs to BigSur 11.5.2.

Ive uninstall and reinstalled homebrew and xcode.

Body:
I faced a similar problem with postgresql 11 and restarting the service did not help. The issue arose when my MacBook restarted abruptly.

After checking the ports and trying out all the possible solutions, I decided to look into the logs.

tail -n 100 /usr/local/var/log/postgresql@11.log

This gave me the last 100 lines of the log where I found this:

FATAL:  lock file "postmaster.pid" already exists
HINT:  Is another postmaster (PID 479) running in data directory "/usr/local/var/postgresql@11"?

Clearly, the issue was with postmaster.pid so I deleted it:

rm /usr/local/var/postgresql@11/postmaster.pid

Started the postgres service again:

brew services start postgresql@11

and voila! It worked.


问:
Adding elements to C++ vector
I want to learn more about C++ coding, especially to design and create a desktop application.

To begin, I want to create a notification app where I can make a task by giving the task a name and content. For this, I use 2 vectors (name and content).

I initialize the vectors like this:

```<code>std::vector <LPWSTR> NameTask;
std::vector <LPWSTR> ContentTask;
</code>```

After, I simply create a button to add the name and content into the vectors:

```<code>if (wmId == ID_BUTTON) {
    //local variables (only for the Button event)
    int len_name = GetWindowTextLength(TextBox_Name) + 1; //give the lenght value of the text in the textbox
    int len_content = GetWindowTextLength(TextBox_content) + 1; //give the lenght value of the text in the textbox
    wchar_t Text_name[100] = L""; //Wchar is compatible with LPWSTR
    wchar_t Text_content[100] = L""; //Wchar is compatible with LPWSTR

    // get the text of the Text edit and put it in local variable name and content
    GetWindowText(TextBox_Name, Text_name, len_name);
    GetWindowText(TextBox_content, Text_content, len_content);
    //verify if the texts are empty
    if (wcslen(Text_name) == 0 || wcslen(Text_content) == 0) {
        MessageBox(hWnd, L"name and content can't be empty", L"MessageBox", MB_OK);
    }
    else {
        NameTask.push_back(Text_name); // set name of task in vector of NameTask
        ContentTask.push_back (Text_name); // set content of task in vector of ContentTask
        //ComboBox_AddString(Combobox, Text_name); // add the title of the task in the combotext
        //SetWindowText(TextBox_Name, L""); //empty the textbox
        SetWindowText(TextBox_content, NameTask.at(0)); // visualize first element of vector name
    }
}
</code>```

The problem that I have is that, when I add a new element to the vector, and then I go to visualize it, it always shows me the last element added. Even when I use SetWindowText(TextBox_content, NameTask.at(0));

And when I use another button to visualize the name and content, it gives a strange output:

答:
I don't know what you really want to do. At first, i would change the wchar_t to std::wstring. This way you don't need to specify the size. But, here I have a sugestion

```<code>if (wmId == ID_BUTTON) {
        //local variables (only for the Button event)
        int len_name = GetWindowTextLength(TextBox_Name) + 1; //give the lenght value of the text in the textbox
        int len_content = GetWindowTextLength(TextBox_content) + 1; //give the lenght value of the text in the textbox
        std::wstring Text_name = L""; //Wchar is compatible with LPWSTR
        std::wstring Text_content = L""; //Wchar is compatible with LPWSTR

        // get the text of the Text edit and put it in local variable name and content
        GetWindowText(TextBox_Name, Text_name, len_name);
        GetWindowText(TextBox_content, Text_content, len_content);
        //verify if the texts are empty
        if (wcslen(Text_name) == 0 || wcslen(Text_content) == 0) {
            MessageBox(hWnd, L"name and content can't be empty", L"MessageBox", MB_OK);
        }
        else {
            NameTask.push_back(Text_name); // set name of task in vector of NameTask
            ContentTask.push_back (Text_name); // set content of task in vector of ContentTask
            //ComboBox_AddString(Combobox, Text_name); // add the title of the task in the combotext
            //SetWindowText(TextBox_Name, L""); //empty the textbox
            SetWindowText(TextBox_content, NameTask.at(0)); // visualize first element of vector name
        }
    }
</code>```

Title: Adding elements to C++ vector

Body:
I want to learn more about C++ coding, especially to design and create a desktop application.

To begin, I want to create a notification app where I can make a task by giving the task a name and content. For this, I use 2 vectors (name and content).

I initialize the vectors like this:

std::vector <LPWSTR> NameTask;
std::vector <LPWSTR> ContentTask;

After, I simply create a button to add the name and content into the vectors:

if (wmId == ID_BUTTON) {
    //local variables (only for the Button event)
    int len_name = GetWindowTextLength(TextBox_Name) + 1; //give the lenght value of the text in the textbox
    int len_content = GetWindowTextLength(TextBox_content) + 1; //give the lenght value of the text in the textbox
    wchar_t Text_name[100] = L""; //Wchar is compatible with LPWSTR
    wchar_t Text_content[100] = L""; //Wchar is compatible with LPWSTR

    // get the text of the Text edit and put it in local variable name and content
    GetWindowText(TextBox_Name, Text_name, len_name);
    GetWindowText(TextBox_content, Text_content, len_content);
    //verify if the texts are empty
    if (wcslen(Text_name) == 0 || wcslen(Text_content) == 0) {
        MessageBox(hWnd, L"name and content can't be empty", L"MessageBox", MB_OK);
    }
    else {
        NameTask.push_back(Text_name); // set name of task in vector of NameTask
        ContentTask.push_back (Text_name); // set content of task in vector of ContentTask
        //ComboBox_AddString(Combobox, Text_name); // add the title of the task in the combotext
        //SetWindowText(TextBox_Name, L""); //empty the textbox
        SetWindowText(TextBox_content, NameTask.at(0)); // visualize first element of vector name
    }
}

The problem that I have is that, when I add a new element to the vector, and then I go to visualize it, it always shows me the last element added. Even when I use SetWindowText(TextBox_content, NameTask.at(0));

And when I use another button to visualize the name and content, it gives a strange output:

Body:
I don't know what you really want to do. At first, i would change the wchar_t to std::wstring. This way you don't need to specify the size. But, here I have a sugestion

if (wmId == ID_BUTTON) {
        //local variables (only for the Button event)
        int len_name = GetWindowTextLength(TextBox_Name) + 1; //give the lenght value of the text in the textbox
        int len_content = GetWindowTextLength(TextBox_content) + 1; //give the lenght value of the text in the textbox
        std::wstring Text_name = L""; //Wchar is compatible with LPWSTR
        std::wstring Text_content = L""; //Wchar is compatible with LPWSTR

        // get the text of the Text edit and put it in local variable name and content
        GetWindowText(TextBox_Name, Text_name, len_name);
        GetWindowText(TextBox_content, Text_content, len_content);
        //verify if the texts are empty
        if (wcslen(Text_name) == 0 || wcslen(Text_content) == 0) {
            MessageBox(hWnd, L"name and content can't be empty", L"MessageBox", MB_OK);
        }
        else {
            NameTask.push_back(Text_name); // set name of task in vector of NameTask
            ContentTask.push_back (Text_name); // set content of task in vector of ContentTask
            //ComboBox_AddString(Combobox, Text_name); // add the title of the task in the combotext
            //SetWindowText(TextBox_Name, L""); //empty the textbox
            SetWindowText(TextBox_content, NameTask.at(0)); // visualize first element of vector name
        }
    }


问:
Convert integer from (pure) binary to BCD
I'm to stupid right now to solve this problem...

I get a BCD number (every digit is an own 4Bit representation)

For example, what I want:

Input: 202 (hex) == 514 (dec)

Output: BCD 0x415

Input: 0x202

Bit-representation: 0010 0000 0010 = 514

What have I tried:

```<code>unsigned int uiValue = 0x202;
unsigned int uiResult = 0;
unsigned int uiMultiplier = 1;
unsigned int uiDigit = 0;

// get the dec bcd value
while ( uiValue > 0 )
{
    uiDigit= uiValue & 0x0F;
    uiValue >>= 4;
    uiResult += uiMultiplier * uiDigit;
    uiMultiplier *= 10;
}
</code>```

But I know that's very wrong this would be 202 in Bit representation and then split into 5 nibbles and then represented as decimal number again

I can solve the problem on paper but I just cant get it in a simple C-Code

答:
You can also try the following:

In every iteration the remainder ( represented as a nibble ) is positioned in its corresponding place.

```<code>uint32_t bcd_converter(int num)
{
  uint32_t temp=0;
  int i=0;
  while(num>0){
    temp|=((num%10)<<i);
    i+=4;
    num/=10;
  }

  return temp;
}

</code>```

Body:
I'm to stupid right now to solve this problem...

I get a BCD number (every digit is an own 4Bit representation)

For example, what I want:

Input: 202 (hex) == 514 (dec)

Output: BCD 0x415

Input: 0x202

Bit-representation: 0010 0000 0010 = 514

What have I tried:

unsigned int uiValue = 0x202;
unsigned int uiResult = 0;
unsigned int uiMultiplier = 1;
unsigned int uiDigit = 0;

// get the dec bcd value
while ( uiValue > 0 )
{
    uiDigit= uiValue & 0x0F;
    uiValue >>= 4;
    uiResult += uiMultiplier * uiDigit;
    uiMultiplier *= 10;
}

But I know that's very wrong this would be 202 in Bit representation and then split into 5 nibbles and then represented as decimal number again

I can solve the problem on paper but I just cant get it in a simple C-Code

Body:
You can also try the following:

In every iteration the remainder ( represented as a nibble ) is positioned in its corresponding place.

uint32_t bcd_converter(int num)
{
  uint32_t temp=0;
  int i=0;
  while(num>0){
    temp|=((num%10)<<i);
    i+=4;
    num/=10;
  }

  return temp;
}


问:
How to pass data using NotificationCenter in swift 3.0 and NSNotificationCenter in swift 2.0?
I'm implementing socket.io in my swift ios app.

Currently on several panels I'm listening to the server and wait for incoming messages. I'm doing so by calling the getChatMessage function in each panel:

```<code>func getChatMessage(){
    SocketIOManager.sharedInstance.getChatMessage { (messageInfo) -> Void in
        dispatch_async(dispatch_get_main_queue(), { () -> Void in
            //do sth depending on which panel user is
        })
    }
}
</code>```

However I noticed it's a wrong approach and I need to change it - now I want to start listening for incoming messages only once and when any message comes - pass this message to any panel that listens to it.

So I want to pass the incoming message through the NSNotificationCenter. So far I was able to pass the information that something happened, but not pass the data itself. I was doing that by:

```<code>NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(ViewController.showSpinningWheel(_:)), name: showSpinner, object: nil)
</code>```

then I had a function called:

```<code>func showSpinningWheel(notification: NSNotification) {
}
</code>```

and any time I wanted to call it I was doing:

```<code>NSNotificationCenter.defaultCenter().postNotificationName(hideSpinner, object: self)
</code>```

So how can I pass the object messageInfo and include it in the function that gets called?

答:
Swift 5.5 with avoid #selector():

First of all, declare the name:

```<code>extension Notification.Name {
    static let prettyName = Notification.Name("MyPrettyName")
}
</code>```

Next is to add observer (take care with queue):

```<code>// For example transferred data should implement protocol
protocol PrettyDelegate {
    func doSomethingAwesome()
}

// Here is the way how we can subscribe as observer
NotificationCenter.default.addObserver(forName: .prettyName, object: nil, queue: nil) { [weak self] notif in
    guard let self = self else { return } // Because self used more than once
    if let userInfo = notif.userInfo,
       let delegate = userInfo["pretty"] as? PrettyDelegate {
        self.delegate = delegate
    }

    self.makePretty() // Here we can do anything
}
</code>```

Finally, we can post the notification from another object

```<code>// Here I'll illustrate how to pass optional value as userInfo
var userInfo: [AnyHashable : Any]?
if let prettyDelegate = self as? PrettyDelegate {
    userInfo = ["pretty": prettyDelegate]
}
NotificationCenter.default.post(name: .prettyName, object: nil, userInfo: userInfo)

</code>```

NOTE: Do NOT forget to remove the observer, when you will not need it anymore.

Body:
I'm implementing socket.io in my swift ios app.

Currently on several panels I'm listening to the server and wait for incoming messages. I'm doing so by calling the getChatMessage function in each panel:

func getChatMessage(){
    SocketIOManager.sharedInstance.getChatMessage { (messageInfo) -> Void in
        dispatch_async(dispatch_get_main_queue(), { () -> Void in
            //do sth depending on which panel user is
        })
    }
}

However I noticed it's a wrong approach and I need to change it - now I want to start listening for incoming messages only once and when any message comes - pass this message to any panel that listens to it.

So I want to pass the incoming message through the NSNotificationCenter. So far I was able to pass the information that something happened, but not pass the data itself. I was doing that by:

NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(ViewController.showSpinningWheel(_:)), name: showSpinner, object: nil)

then I had a function called:

func showSpinningWheel(notification: NSNotification) {
}

and any time I wanted to call it I was doing:

NSNotificationCenter.defaultCenter().postNotificationName(hideSpinner, object: self)

So how can I pass the object messageInfo and include it in the function that gets called?

Body:
Swift 5.5 with avoid #selector():

First of all, declare the name:

extension Notification.Name {
    static let prettyName = Notification.Name("MyPrettyName")
}

Next is to add observer (take care with queue):

// For example transferred data should implement protocol
protocol PrettyDelegate {
    func doSomethingAwesome()
}

// Here is the way how we can subscribe as observer
NotificationCenter.default.addObserver(forName: .prettyName, object: nil, queue: nil) { [weak self] notif in
    guard let self = self else { return } // Because self used more than once
    if let userInfo = notif.userInfo,
       let delegate = userInfo["pretty"] as? PrettyDelegate {
        self.delegate = delegate
    }

    self.makePretty() // Here we can do anything
}

Finally, we can post the notification from another object

// Here I'll illustrate how to pass optional value as userInfo
var userInfo: [AnyHashable : Any]?
if let prettyDelegate = self as? PrettyDelegate {
    userInfo = ["pretty": prettyDelegate]
}
NotificationCenter.default.post(name: .prettyName, object: nil, userInfo: userInfo)

NOTE: Do NOT forget to remove the observer, when you will not need it anymore.


问:
Crash at PHPhotoLibrary presentLimitedLibraryPickerFromViewController line unrecognised selector send to instance
I am trying to present the Limited image picker but i get

```<code>Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[PHPhotoLibrary presentLimitedLibraryPickerFromViewController:]
</code>```

I am using

```<code>#import <Photos/Photos.h>
#import <PhotosUI/PhotosUI.h>
</code>```

This line crashes although self is a viewcontroller

```<code>   [[PHPhotoLibrary sharedPhotoLibrary] presentLimitedLibraryPickerFromViewController:self];
</code>```

Any ideas why?

答:
Quick searching finds:

Possibly a "bug" ... possibly faulty documentation...

Add PhotosUI.framework to your target:

Body:
I am trying to present the Limited image picker but i get

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[PHPhotoLibrary presentLimitedLibraryPickerFromViewController:]

I am using

#import <Photos/Photos.h>
#import <PhotosUI/PhotosUI.h>

This line crashes although self is a viewcontroller

   [[PHPhotoLibrary sharedPhotoLibrary] presentLimitedLibraryPickerFromViewController:self];

Any ideas why?


问:
In a grouped SQL query, efficiently discard groups that have or do not have some values in a column
I am trying to construct a query that aggregates records in a table while filtering out groups based on constraints that involve the presence or absence of certain values in one of the columns. Here is some example data:

CREATE TABLE test (
person_id smallint,
position_id smallint
);

INSERT INTO test
VALUES (1, 30), (1, 99), (1, 98), (2, 98), (2, 99), (3, 30), (3, 28);

SELECT * FROM test;
```
```+-----------+-------------+
| person_id | position_id |
+-----------+-------------+
|         1 |          30 |
|         1 |          99 |
|         1 |          98 |
|         2 |          98 |
|         2 |          99 |
|         3 |          30 |
|         3 |          28 |
+-----------+-------------+
```
<p>I want to aggregate this over person_id, but only for persons who have position 30, and do not have position 28 (for example). The correct query result should be:</p>
```+-----------+------------+
| person_id | positions  |
+-----------+------------+
|         1 | 30, 99, 98 |
+-----------+------------+
```
<p>The question is, <strong>how to do this efficiently?</strong> The actual table I will be doing this on is larger.</p>
<p>I have two working queries that get the correct result:</p>
<pre class="lang-sql prettyprint-override"><code>SELECT person_id, Group_concat(position_id SEPARATOR ', ') AS positions
FROM test
GROUP BY person_id
HAVING Sum(CASE WHEN position_id = 30 THEN 1 ELSE 0 END) > 0
AND Sum(CASE WHEN position_id = 28 THEN 1 ELSE 0 END) = 0;

SELECT person_id, Group_concat(position_id SEPARATOR ', ') AS positions
FROM test
GROUP BY person_id
HAVING Max(position_id = 30) = 1
AND Max(position_id = 28) = 0;
</code>```

However, it seems to me that it shouldn't be necessary to actually do the full aggregations (with Sum() or Max()) for each group, like these queries do, and that it would be more efficient to reformulate this using logical 'any' conditions. E.g.

the first time I encounter a '30' position_id, I have satisfied the first condition;

the first time I encounter a '28' position_id, I have failed the second condition;

there is no need to proceed through the rest of the position_id's for a group after that. However, I'm not sure how to do that, and maybe I am in any case on the wrong track here.

This is using MySQL 8.

答:
You could try using a subquery to identify if the person matches your constraints.

SELECT person_id, Group_concat(position_id SEPARATOR ', ') AS positions
FROM test
WHERE 28 NOT IN (
  SELECT position_id
  FROM test AS ti
  WHERE ti.person_id = test.person_id
) AND 30 IN (
  SELECT position_id
  FROM test AS ti
  WHERE ti.person_id = test.person_id
)
GROUP BY person_id;
```

However as long as you don't analyze the query execution plan any performance improvement is only guessing.

Body:
I am trying to construct a query that aggregates records in a table while filtering out groups based on constraints that involve the presence or absence of certain values in one of the columns. Here is some example data:

CREATE TABLE test (
person_id smallint,
position_id smallint
);

INSERT INTO test
VALUES (1, 30), (1, 99), (1, 98), (2, 98), (2, 99), (3, 30), (3, 28);

SELECT * FROM test;

+-----------+-------------+
| person_id | position_id |
+-----------+-------------+
|         1 |          30 |
|         1 |          99 |
|         1 |          98 |
|         2 |          98 |
|         2 |          99 |
|         3 |          30 |
|         3 |          28 |
+-----------+-------------+

I want to aggregate this over person_id, but only for persons who have position 30, and do not have position 28 (for example). The correct query result should be:

+-----------+------------+
| person_id | positions  |
+-----------+------------+
|         1 | 30, 99, 98 |
+-----------+------------+

The question is, how to do this efficiently? The actual table I will be doing this on is larger.

I have two working queries that get the correct result:

SELECT person_id, Group_concat(position_id SEPARATOR ', ') AS positions
FROM test
GROUP BY person_id
HAVING Sum(CASE WHEN position_id = 30 THEN 1 ELSE 0 END) > 0
AND Sum(CASE WHEN position_id = 28 THEN 1 ELSE 0 END) = 0;

SELECT person_id, Group_concat(position_id SEPARATOR ', ') AS positions
FROM test
GROUP BY person_id
HAVING Max(position_id = 30) = 1
AND Max(position_id = 28) = 0;

However, it seems to me that it shouldn't be necessary to actually do the full aggregations (with Sum() or Max()) for each group, like these queries do, and that it would be more efficient to reformulate this using logical 'any' conditions. E.g.

the first time I encounter a '30' position_id, I have satisfied the first condition;

the first time I encounter a '28' position_id, I have failed the second condition;

there is no need to proceed through the rest of the position_id's for a group after that. However, I'm not sure how to do that, and maybe I am in any case on the wrong track here.

This is using MySQL 8.

Body:
You could try using a subquery to identify if the person matches your constraints.

SELECT person_id, Group_concat(position_id SEPARATOR ', ') AS positions
FROM test
WHERE 28 NOT IN (
  SELECT position_id
  FROM test AS ti
  WHERE ti.person_id = test.person_id
) AND 30 IN (
  SELECT position_id
  FROM test AS ti
  WHERE ti.person_id = test.person_id
)
GROUP BY person_id;

However as long as you don't analyze the query execution plan any performance improvement is only guessing.


问:
Is there a way to set the index name in the DataFrame constructor?
Is it possible to set the index name inside the pd.DataFrame() constructor instead of the way I'm doing it below?

```<code>In [1]: df = pd.DataFrame({'s': [-1], 'count':[1]}, index = pd.date_range('2022-02-07', periods=1))

In [2]: index = df.index

In [3]: index.name = 'Date'

In [4]: df
Out[4]:
            s  count
Date
2022-02-07 -1      1
</code>```

答:
Use  name parameter in date_range:

```<code>df = pd.DataFrame({'s': [-1], 'count':[1]},
                   index = pd.date_range('2022-02-07', periods=1, name='Date'))
print (df)
            s  count
Date
2022-02-07 -1      1
</code>```

Or use rename:

```<code>df = pd.DataFrame({'s': [-1], 'count':[1]},
                   index = pd.date_range('2022-02-07', periods=1).rename('Date'))
</code>```

Body:
Is it possible to set the index name inside the pd.DataFrame() constructor instead of the way I'm doing it below?

In [1]: df = pd.DataFrame({'s': [-1], 'count':[1]}, index = pd.date_range('2022-02-07', periods=1))

In [2]: index = df.index

In [3]: index.name = 'Date'

In [4]: df
Out[4]:
            s  count
Date
2022-02-07 -1      1

Body:
Use  name parameter in date_range:

df = pd.DataFrame({'s': [-1], 'count':[1]},
                   index = pd.date_range('2022-02-07', periods=1, name='Date'))
print (df)
            s  count
Date
2022-02-07 -1      1

Or use rename:

df = pd.DataFrame({'s': [-1], 'count':[1]},
                   index = pd.date_range('2022-02-07', periods=1).rename('Date'))


问:
how to update multiple records with jdbc with oracle and spring boot
I am trying to update several records from spring jdbc but this is not working what am i doing wrong?

does not respond when I make a request, but the data in the array is arriving, try without array and the same thing happens.

I am sending an array of objects to be able to update but I get to the method cstmt.executeQuery(); it does not execute and it waits and does not go any further.

```<code>@PostMapping(path = "/updateEstadoPlanesServicios", produces = MediaType.APPLICATION_JSON)
    public String updateEstadoPlanesServicios(@RequestBody String lista)  {

        ServiciosPlanesUpdateDTO[] fromJson = gson.fromJson(lista, ServiciosPlanesUpdateDTO[].class);

            return gson.toJson(consultaPlanesComisionPortal.estadoPlanesServicios(fromJson));

    }
</code>```
```<code>    @Transactional(rollbackFor = { Exception.class })
    public replyDTO estadoPlanesServicios(ServiciosPlanesUpdateDTO[] list) {
        System.out.println("data: "+list.toString());
        replyDTO  re = new replyDTO();
        int count = 0;

        try {

            StringBuilder update = new StringBuilder();
            update.append("UPDATE Detalleproductoservicio ");
            update.append(" SET loginregistro  =  ?,  estado  =  'D',  fechasys  =  sysdate ");
            update.append(" WHERE  codigo_Servicio  =  ?  and  codigo_planproductoservicio  =  ? and  NIT  =  ?");

            try (Connection conexion = obtenerConexion.obtenerConexion(0);
                    PreparedStatement cstmt = conexion.prepareStatement(update.toString())) {
                conexion.setAutoCommit(false);

                for(ServiciosPlanesUpdateDTO elements: list) {
                    //System.out.println(elements.toString());
                    System.out.println("1 element:"+elements.getLoginRegistro());
                    System.out.println("2 element:"+elements.getCodigoServicio());
                    System.out.println("3 element:"+elements.getCodigoPlanProductoServicio());
                    System.out.println("4 element:"+elements.getNit());
                    cstmt.setString(1, elements.getLoginRegistro().trim());
                    cstmt.setInt(2,Integer.parseInt( elements.getCodigoServicio().trim()));
                    cstmt.setString(3, elements.getCodigoPlanProductoServicio().trim());
                    cstmt.setString(4, elements.getNit().trim());

                    count = cstmt.executeUpdate();
                    //cstmt.execute();
                    //count++;
                    //cstmt.addBatch();
                    //cstmt.executeBatch();
                    //

                }

                conexion.commit();
                if(count > 0) {
                    re.setMessage("Status ok,"
                            +"count: "+count);
                    re.setExitoso(true);
                }else {
                    re.setExitoso(false);
                    re.setMessage("failed");
                }

            }

        } catch (Exception  e ) {

            re.setExitoso(false);
            re.setMessage(e.getMessage());
        }
        return re;
    }

</code>```

答: this is working I found the problem apparently the database conflicts when I have Oracle SQL Developer open and I make the request by postman this is a little weird but I closed Oracle Developer and it worked.</p>

Body:
I am trying to update several records from spring jdbc but this is not working what am i doing wrong?

does not respond when I make a request, but the data in the array is arriving, try without array and the same thing happens.

I am sending an array of objects to be able to update but I get to the method cstmt.executeQuery(); it does not execute and it waits and does not go any further.

@PostMapping(path = "/updateEstadoPlanesServicios", produces = MediaType.APPLICATION_JSON)
    public String updateEstadoPlanesServicios(@RequestBody String lista)  {

        ServiciosPlanesUpdateDTO[] fromJson = gson.fromJson(lista, ServiciosPlanesUpdateDTO[].class);

            return gson.toJson(consultaPlanesComisionPortal.estadoPlanesServicios(fromJson));

    }

    @Transactional(rollbackFor = { Exception.class })
    public replyDTO estadoPlanesServicios(ServiciosPlanesUpdateDTO[] list) {
        System.out.println("data: "+list.toString());
        replyDTO  re = new replyDTO();
        int count = 0;

        try {

            StringBuilder update = new StringBuilder();
            update.append("UPDATE Detalleproductoservicio ");
            update.append(" SET loginregistro  =  ?,  estado  =  'D',  fechasys  =  sysdate ");
            update.append(" WHERE  codigo_Servicio  =  ?  and  codigo_planproductoservicio  =  ? and  NIT  =  ?");

            try (Connection conexion = obtenerConexion.obtenerConexion(0);
                    PreparedStatement cstmt = conexion.prepareStatement(update.toString())) {
                conexion.setAutoCommit(false);

                for(ServiciosPlanesUpdateDTO elements: list) {
                    //System.out.println(elements.toString());
                    System.out.println("1 element:"+elements.getLoginRegistro());
                    System.out.println("2 element:"+elements.getCodigoServicio());
                    System.out.println("3 element:"+elements.getCodigoPlanProductoServicio());
                    System.out.println("4 element:"+elements.getNit());
                    cstmt.setString(1, elements.getLoginRegistro().trim());
                    cstmt.setInt(2,Integer.parseInt( elements.getCodigoServicio().trim()));
                    cstmt.setString(3, elements.getCodigoPlanProductoServicio().trim());
                    cstmt.setString(4, elements.getNit().trim());

                    count = cstmt.executeUpdate();
                    //cstmt.execute();
                    //count++;
                    //cstmt.addBatch();
                    //cstmt.executeBatch();
                    //

                }

                conexion.commit();
                if(count > 0) {
                    re.setMessage("Status ok,"
                            +"count: "+count);
                    re.setExitoso(true);
                }else {
                    re.setExitoso(false);
                    re.setMessage("failed");
                }

            }

        } catch (Exception  e ) {

            re.setExitoso(false);
            re.setMessage(e.getMessage());
        }
        return re;
    }


问:
Filter object by property and select with key in jmespath
I'm trying to filter properties of an object in jmespath based on the value of a subproperty and want to include only those properties where the subproperty is set to a specific value.

Based on this example data:

```<code>{
  "a": {
    "feature": {
      "enabled": true,
    }
  },
  "b": {
  },
  "c": {
    "feature": {
      "enabled": false
     }
  }
}
</code>```

I'd like to get an object with all properties where the feature is enabled.

```<code>{
  "a": {
    "feature": {
      "enabled": true,
    }
  }
}
</code>```

I figured I could use this jmespath query to filter the objects where property. enabled is set to true. Unfortunateley, it doesn't seem to work and instead returns an empty array.

```<code>*[?feature.enabled==`true`]
</code>```

*.feature.enabled or *[feature.enabled] return just the boolean values without any context.

Even if *[?feature.enabled==true] would work, it would just be an array of the property values, but I need the keys (a and c) aswell. Is there any way to make this happen in jmespath?

This is all part of an ansible playbook, so there would certainly be a way to achieve selection in a different way (Jinja2 templates or custom plugin) but I wanted to try jmespath and would reason, that it should be capable of such a task.

答:
You can use:</p>
```<code><json_data>|[*]|[? @.feature.enabled]
</code>```

Body:
I'm trying to filter properties of an object in jmespath based on the value of a subproperty and want to include only those properties where the subproperty is set to a specific value.

Based on this example data:

{
  "a": {
    "feature": {
      "enabled": true,
    }
  },
  "b": {
  },
  "c": {
    "feature": {
      "enabled": false
     }
  }
}

I'd like to get an object with all properties where the feature is enabled.

{
  "a": {
    "feature": {
      "enabled": true,
    }
  }
}

I figured I could use this jmespath query to filter the objects where property. enabled is set to true. Unfortunateley, it doesn't seem to work and instead returns an empty array.

*[?feature.enabled==`true`]

*.feature.enabled or *[feature.enabled] return just the boolean values without any context.

Even if *[?feature.enabled==true] would work, it would just be an array of the property values, but I need the keys (a and c) aswell. Is there any way to make this happen in jmespath?

This is all part of an ansible playbook, so there would certainly be a way to achieve selection in a different way (Jinja2 templates or custom plugin) but I wanted to try jmespath and would reason, that it should be capable of such a task.

Body:
You can use:

<json_data>|[*]|[? @.feature.enabled]


问:
Why does Qt Creator run MOC on all my files?
I have a Qt project with precompiled headers enabled. Compilation was working fine until recently. But since a dew days I've noticed that Qt Creator is always running MOC on all my Q_OBJECT files, even those that haven't been changed. Because of that, many CPP files also need to be rebuilt for no reason.

Is there any reason why that could happen? I'm looking at the compile output but I'm not seeing anything special. Any idea?

答:
Okay I just figured it out. I was playing with my system's date a few days ago to test some time-related functions. Problem is, I edited a few files in Qt Creator at that time so their dates was now in the future. Because of that, qmake was detecting changes where there weren't any.

I've now set back the dates of the files to today's date and the compilation is working again.