public NegatoscopForm() { InitializeComponent(); _currentRamp = new Ramp { Red = new ushort[256], Green = new ushort[256], Blue = new ushort[256] }; Win32Engine.GetDeviceGammaRamp(Win32Engine.GetDC(Handle), ref _currentRamp); var newRamp = new Ramp { Red = new ushort[256], Green = new ushort[256], Blue = new ushort[256] }; for (int i = 1; i < 256; i++) { newRamp.Red[i] = newRamp.Green[i] = newRamp.Blue[i] = (ushort)(Math.Min(65535, Math.Max(0, Math.Pow((i + 1) / 256.0, 44 * 0.1) * 65535 + 0.5))); } Win32Engine.SetDeviceGammaRamp(Win32Engine.GetDC(Handle), ref newRamp); }
/// <summary> /// Заливка области /// </summary> /// <param name="g">Графикс отображаемого объекта (например, панели)</param> /// <param name="pos">Точка, в которой начинается заливка</param> /// <param name="colorFill">Цвет заливки</param> /// <param name="possibleColors">Список серых цветов, которые можно закрашивать</param> private void Fill(Graphics g, Point pos, Color colorFill, IEnumerable <int> possibleColors) { // Цвет в точке, с которой начинается заливка Color colorBegin = _picture.GetPixel(pos.X, pos.Y); bool isColorBeginPossible = false; foreach (int colorValue in possibleColors) { if (colorBegin.R == colorBegin.B && colorBegin.R == colorBegin.G && colorBegin.R == colorValue) { isColorBeginPossible = true; break; } } if (!isColorBeginPossible) { return; } // DC панели IntPtr panelDC = g.GetHdc(); // DC в памяти, совместимый с панелью IntPtr memDC = Win32Engine.CreateCompatibleDC(panelDC); // Создаем и подсовываем свою кисть IntPtr hBrush = Win32Engine.CreateSolidBrush((uint)ColorTranslator.ToWin32(colorFill)); IntPtr hOldBr = Win32Engine.SelectObject(memDC, hBrush); // Подсовываем свой битмап IntPtr hBmp = _picture.GetHbitmap(); IntPtr hOldBmp = Win32Engine.SelectObject(memDC, hBmp); // Заливаем (заливается благодаря совместимости с панелью, в противном случае // заливки на битмапе не произойдет) Win32Engine.ExtFloodFill(memDC, pos.X, pos.Y, (uint)ColorTranslator.ToWin32(colorBegin), 1); // Записываем полученный залитый битмап в наш битмап _picture.Dispose(); _picture = Image.FromHbitmap(hBmp); // Возвращаем на место предыдущие кисть и битмап Win32Engine.SelectObject(memDC, hOldBr); Win32Engine.SelectObject(memDC, hOldBmp); // Освобождаем использованные ресурсы Win32Engine.DeleteObject(hBmp); Win32Engine.DeleteObject(hBrush); Win32Engine.DeleteObject(memDC); g.ReleaseHdc(panelDC); buttonUndo.Visible = true; checkBoxWordExport.Checked = true; }
/// <summary> /// Capture the contents of a window or control /// </summary> /// <param name="control">Control</param> /// <param name="bitmap">Picture</param> private static void CaptureWindow(Control control, ref Bitmap bitmap) { using (Graphics g2 = Graphics.FromImage(bitmap)) { const int meint = (int)(Win32Engine.PRF_CLIENT | Win32Engine.PRF_ERASEBKGND); var meptr = new IntPtr(meint); IntPtr hdc = g2.GetHdc(); Win32Engine.SendMessage(control.Handle, Win32Engine.WM_PRINT, hdc, meptr); g2.ReleaseHdc(hdc); } }
// UPictureBox protected override void WndProc(ref Message m) { if (m.Msg == Win32Engine.WM_LBUTTONDOWN || m.Msg == Win32Engine.WM_RBUTTONDOWN || m.Msg == Win32Engine.WM_LBUTTONDBLCLK || m.Msg == Win32Engine.WM_MOUSELEAVE || m.Msg == Win32Engine.WM_MOUSEMOVE) { // Send the above messages back to the parent control Win32Engine.PostMessage(Parent.Handle, (uint)m.Msg, m.WParam, m.LParam); } else if (m.Msg == Win32Engine.WM_LBUTTONUP) { // ?? for selects and such Parent.Invalidate(); } base.WndProc(ref m); }
// отлов скроллирования // при движении ползунка мышью - срабатывает WmVScroll, получается позиция ползунка и кидается событие VScrollingChange // текущее событие пробрасывается для движения ползунка на текущем контроле // при скроллировании мышью - срабатывает WmMouseWheel, получается текущая позиция ползунка, определяется направление // скроллирования, вычисляется правильное положение ползунка после сдвига и кидается событие VScrollingChange. // Так приходится поступать, потому что это событие происходит до того, как ползунок изменит своё положение. Поэтому // приходится не пробрасывать текущее событие, а генерить своё, с указанием правильного положения ползунка после сдвига, // ибо сдвиг может произойти на любое количество шагов (1, 2, 3 и т.д.). Мы же в итоге сдвигается всегда на один шаг. protected override void WndProc(ref Message m) { if (_stopScrollCatching) { base.WndProc(ref m); return; } int pos; var scrollInfo = new ScrollInfo(); scrollInfo.Size = (uint)Marshal.SizeOf(scrollInfo); switch (m.Msg) { case (int)ScrollMessage.WmVScroll: if (VScrollingChange != null) { if ((m.WParam.ToInt32() & 0xFF) == (int)ScrollBarCommands.ThumbTrack) { scrollInfo.Mask = (uint)ScrollBarInfo.TrackPos; Win32Engine.GetScrollInfo(Handle, (int)ScrollBarType.SbVert, ref scrollInfo); pos = scrollInfo.TrackPos; } else { scrollInfo.Mask = (uint)ScrollBarInfo.Pos; Win32Engine.GetScrollInfo(Handle, (int)ScrollBarType.SbVert, ref scrollInfo); pos = scrollInfo.Pos; } VScrollingChange(this, new CScrollEventArgs(pos)); } break; case (int)ScrollMessage.WmMouseWheel: scrollInfo.Mask = (uint)ScrollBarInfo.Pos; Win32Engine.GetScrollInfo(Handle, (int)ScrollBarType.SbVert, ref scrollInfo); pos = scrollInfo.Pos; if (m.WParam.ToInt32() < 0) { pos++; } else if (pos > 0) { pos--; } if (VScrollingChange != null) { VScrollingChange(this, new CScrollEventArgs(pos)); } _stopScrollCatching = true; pos <<= 16; uint wParam = (uint)ScrollBarCommands.ThumbPosition | (uint)pos; Win32Engine.SendMessage(Handle, (int)ScrollMessage.WmVScroll, new IntPtr(wParam), new IntPtr(0)); _stopScrollCatching = false; return; } base.WndProc(ref m); }
private void NegatoscopForm_FormClosing(object sender, FormClosingEventArgs e) { Win32Engine.SetDeviceGammaRamp(Win32Engine.GetDC(Handle), ref _currentRamp); }