private void getComboButtonWidth() { if (!this.IsHandleCreated) { return; } DATETIMEPICKERINFO pickerInfo = new DATETIMEPICKERINFO() { cbSize = Marshal.SizeOf(typeof(DATETIMEPICKERINFO)) }; IntPtr pickerInfoPointer = Marshal.AllocHGlobal(Marshal.SizeOf(pickerInfo)); Marshal.StructureToPtr(pickerInfo, pickerInfoPointer, false); SendMessage(this.Handle, DTM_GETDATETIMEPICKERINFO, ( IntPtr )0, pickerInfoPointer); pickerInfo = ( DATETIMEPICKERINFO )Marshal.PtrToStructure(pickerInfoPointer, typeof(DATETIMEPICKERINFO)); int buttonWidth = pickerInfo.rcButton.Right - pickerInfo.rcButton.Left; _buttonWidth = buttonWidth; #if DEBUG Console.WriteLine("_buttonWidth = " + _buttonWidth); #endif }
private static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, DATETIMEPICKERINFO lParam);
private void CustomDraw(object sender, PaintEventArgs e) { // ネイティブイメージを描画 var bmpOrg = cdw.NativeClientBitmap; var g = e.Graphics; g.DrawImage(bmpOrg, Point.Empty); // 枠を除いて描画領域とする var bsz = SystemInformation.Border3DSize; var clip = Rectangle.Inflate(this.ClientRectangle, -bsz.Width, -bsz.Height); IntPtr hdc = g.GetHdc(); try { // BackColor を反映 using (var bmpBack = (Bitmap)bmpOrg.Clone()) { BitBlt(bmpBack, BackColor, SRCAND); BitBlt(hdc, bmpBack, clip, SRCCOPY); } // ForeColor を反映 using (var bmpFore = CreateNegativeBitmap(bmpOrg)) { Color foreColor = IsDisable ? Color.Gray : ForeColor; BitBlt(bmpFore, foreColor, SRCAND); BitBlt(hdc, bmpFore, clip, SRCPAINT); } // レイアウト(チェックボックスとボタンの位置)を取得 var dti = new DATETIMEPICKERINFO(); SendMessage(this.Handle, DTM_GETDATETIMEPICKERINFO, IntPtr.Zero, dti); Rectangle checkBox = dti.rcCheck.Rectangle; Rectangle button = dti.rcButton.Rectangle; // チェックボックスを描画 if (!checkBox.IsEmpty) { // チェックボックスの領域をネイティブイメージより描画 BitBlt(hdc, bmpOrg, checkBox, SRCCOPY); } // アップダウンコントロールがある場合はその領域をボタン領域とする if (dti.hwndUD != IntPtr.Zero) { GetWindowRect(dti.hwndUD, out RECT rc); button = RectangleToClient(rc.Rectangle); } // ボタンを描画 if (!button.IsEmpty) { // ボタンの領域をネイティブイメージより描画 BitBlt(hdc, bmpOrg, button, SRCCOPY); } // フォーカスがあるとき、キャレットの部分のみ転送 if (this.ContainsFocus) { // キャレットの色を検索する領域を設定 var left = clip.Left; var right = clip.Right; if (!checkBox.IsEmpty) { left = checkBox.Right; } if (!button.IsEmpty) { right = button.Left; } var canvas = Rectangle.FromLTRB(left, clip.Top, right, clip.Bottom); Rectangle caret = GetCaretRectangle(bmpOrg, canvas); if (!caret.IsEmpty) { BitBlt(hdc, bmpOrg, caret, SRCCOPY); } } } finally { g.ReleaseHdc(); } }
static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, ref DATETIMEPICKERINFO info);
protected override void WndProc(ref Message m) { if (m.Msg == WM_PAINT) { var info = new DATETIMEPICKERINFO(); info.cbSize = Marshal.SizeOf(info); SendMessage(Handle, DTM_GETDATETIMEPICKERINFO, IntPtr.Zero, ref info); var clientRect = new Rectangle(0, 0, Width, Height); var dropDownButtonRect = new Rectangle(info.rcButton.L, info.rcButton.T, info.rcButton.R - info.rcButton.L, clientRect.Height); var dropDownRect = dropDownButtonRect; var imageRect = Rectangle.Empty; if (info.rcButton.R - info.rcButton.L > SystemInformation.HorizontalScrollBarArrowWidth) { var w = dropDownButtonRect.Width / 2; imageRect = dropDownButtonRect; imageRect.Width = w; dropDownRect.X += w; dropDownRect.Width = w; } var checkBoxRect = new Rectangle(info.rcCheck.L, info.rcCheck.T, info.rcCheck.R - info.rcCheck.L, clientRect.Height); var innerRect = new Rectangle(checkBoxRect.Right + 1, 1, clientRect.Width - dropDownButtonRect.Width - checkBoxRect.Width - (ShowCheckBox ? 3 : 1), clientRect.Height - 2); if (RightToLeft == RightToLeft.Yes && RightToLeftLayout == true) { dropDownButtonRect.X = clientRect.Width - dropDownButtonRect.Right; dropDownButtonRect.Width += 1; innerRect.X -= clientRect.Width - innerRect.X; innerRect.Width += 1; imageRect.X = clientRect.Width - imageRect.Right; dropDownRect.X = clientRect.Width - dropDownRect.Right; dropDownRect.Width += 1; } var middle = new Point(dropDownRect.Left + dropDownRect.Width / 2, dropDownRect.Top + dropDownRect.Height / 2); var arrow = new Point[] { new Point(middle.X - 3, middle.Y - 2), new Point(middle.X + 4, middle.Y - 2), new Point(middle.X, middle.Y + 2) }; var borderColor = Enabled ? BorderColor : Color.LightGray; var ps = new PAINTSTRUCT(); bool shoulEndPaint = false; IntPtr dc; if (m.WParam == IntPtr.Zero) { dc = BeginPaint(Handle, ref ps); m.WParam = dc; shoulEndPaint = true; } else { dc = m.WParam; } var rgn = CreateRectRgn(innerRect.Left, innerRect.Top, innerRect.Right, innerRect.Bottom); SelectClipRgn(dc, rgn); DefWndProc(ref m); DeleteObject(rgn); rgn = CreateRectRgn(clientRect.Left, clientRect.Top, clientRect.Right, clientRect.Bottom); SelectClipRgn(dc, rgn); using (var g = Graphics.FromHdc(dc)) { if (ShowCheckBox) { var r = Rectangle.FromLTRB(info.rcCheck.L, info.rcCheck.T, info.rcCheck.R, info.rcCheck.B); if (Checked) { DrawFrameControl(dc, ref info.rcCheck, DFC_MENU, DFCS_MENUCHECK); } else { g.FillRectangle(SystemBrushes.Window, r); } if (!Enabled) { using (var b = new SolidBrush(Color.FromArgb(200, SystemColors.Control))) g.FillRectangle(b, r); } var r2 = r; r2.Width -= 1; r2.Height -= 1; g.DrawRectangle(Enabled ? SystemPens.WindowText : SystemPens.GrayText, r2); r2.Inflate(1, 1); g.DrawRectangle(Pens.White, r2); } if (ShowUpDown) { if (updownRenderer == null && info.hwndUD != IntPtr.Zero) { updownRenderer = new UpDownRenderer(info.hwndUD); } updownRenderer.ButtonColor = this.BorderColor; updownRenderer.ArrowColor = Color.Black; } else { var buttonColor = Enabled ? BorderColor : Color.LightGray; var arrorColor = Color.Black; var imageToRender = calendarImage; if (dropDownButtonRect.Contains(PointToClient(Cursor.Position))) { arrorColor = Color.White; imageToRender = calendarImageWhite; } using (var brush = new SolidBrush(buttonColor)) g.FillRectangle(brush, dropDownButtonRect); if (imageRect != Rectangle.Empty) { g.DrawImage(imageToRender, imageRect.Left + ((imageRect.Width - imageToRender.Width) / 2), imageRect.Top + ((imageRect.Height - imageToRender.Height) / 2), calendarImage.Width, calendarImage.Height); } using (var brush = new SolidBrush(arrorColor)) g.FillPolygon(brush, arrow); } using (var pen = new Pen(borderColor)) g.DrawRectangle(pen, 0, 0, ClientRectangle.Width - 1, ClientRectangle.Height - 1); } if (shoulEndPaint) { EndPaint(Handle, ref ps); } DeleteObject(rgn); } else { base.WndProc(ref m); } }