protected override void WndProc(ref System.Windows.Forms.Message m) { switch (m.Msg) { case NativeMethods.WM_DWMCOMPOSITIONCHANGED: if (this.glassSet) { this.ExtendFrameIntoClientArea(); } break; case NativeMethods.WM_NCHITTEST: this.DefWndProc(ref m); if (OsUtils.WinVistaOrLater() && VisualStyleRenderer.IsSupported && this.glassSet) { if ((int)m.Result == NativeMethods.HTCLIENT) { // Pretend that the mouse was over the title bar, making the form draggable m.Result = (IntPtr)NativeMethods.HTCAPTION; return; } } break; } base.WndProc(ref m); }
public void SetWholeDropDown(ToolBarButton button) { if (button == null) { throw new ArgumentNullException("button"); } if (!this.wholeDropDownButtons.Contains(button)) { this.wholeDropDownButtons.Add(button); if (!OsUtils.Windows()) { // Append a down arrow as BTNS_WHOLEDROPDOWN is only supported under Windows button.Text += " ▾"; } } NativeMethods.TBBUTTONINFO buttonInfo = default(NativeMethods.TBBUTTONINFO); buttonInfo.cbSize = Marshal.SizeOf(buttonInfo); buttonInfo.dwMask = NativeMethods.TBIF_STYLE | NativeMethods.TBIF_BYINDEX; buttonInfo.fsStyle = NativeMethods.BTNS_WHOLEDROPDOWN | NativeMethods.BTNS_AUTOSIZE; NativeMethods.SendMessage(this.Handle, NativeMethods.TB_SETBUTTONINFO, (IntPtr)this.Buttons.IndexOf(button), ref buttonInfo); }
private void ButtonOk_Click(object eventSender, EventArgs eventArgs) { if (string.IsNullOrEmpty(this.TextFileNameFormat.Text)) { Interaction.MsgBox("Please enter a value for the downloaded programme file name format.", MsgBoxStyle.Exclamation); this.TextFileNameFormat.Focus(); this.cancelClose = true; return; } bool formatChanged = Settings.FileNameFormat != this.TextFileNameFormat.Text; if (this.folderChanged || formatChanged) { string message = "Move existing downloads to \"" + this.TextSaveIn.Text + "\" and rename to new naming format?"; if (!formatChanged) { message = "Move existing downloads to \"" + this.TextSaveIn.Text + "\"?"; } else if (!this.folderChanged) { message = "Rename existing downloads to new naming format?"; } if (MessageBox.Show(message, Application.ProductName, MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) { using (Status status = new Status()) { status.ShowDialog( this, delegate { Model.Download.UpdatePaths(status, this.TextSaveIn.Text, this.TextFileNameFormat.Text); }); } } Settings.SaveFolder = this.TextSaveIn.Text; Settings.FileNameFormat = this.TextFileNameFormat.Text; } Settings.RunOnStartup = this.CheckRunOnStartup.Checked; Settings.RunAfterCommand = this.TextRunAfter.Text; Settings.ParallelDownloads = (int)this.NumberParallel.Value; Settings.RssServer = this.CheckRssServer.Checked; if (this.CheckRssServer.Checked) { Settings.RssServerPort = (int)this.NumberServerPort.Value; Settings.RssServerNumRecentEps = (int)this.NumberEpisodes.Value; } if (OsUtils.WinSevenOrLater()) { Settings.CloseToSystray = this.CheckCloseToSystray.Checked; } OsUtils.ApplyRunOnStartup(); }
private void Preferences_Load(object eventSender, EventArgs eventArgs) { this.Font = SystemFonts.MessageBoxFont; this.CheckRunOnStartup.Checked = Settings.RunOnStartup; if (OsUtils.WinSevenOrLater()) { this.CheckCloseToSystray.Checked = Settings.CloseToSystray; } else { this.CheckCloseToSystray.Checked = true; this.CheckCloseToSystray.Enabled = false; } this.NumberParallel.Value = Settings.ParallelDownloads; this.NumberParallel.Maximum = Math.Max(this.NumberParallel.Value, Environment.ProcessorCount * 2); try { this.TextSaveIn.Text = FileUtils.GetSaveFolder(); } catch (DirectoryNotFoundException) { this.TextSaveIn.Text = Settings.SaveFolder; } this.TextFileNameFormat.Text = Settings.FileNameFormat; this.TextRunAfter.Text = Settings.RunAfterCommand; }
protected override void OnRenderButtonBackground(ToolStripItemRenderEventArgs e) { if (e.Item.DisplayStyle == ToolStripItemDisplayStyle.Image) { // Do not paint a background for icon only buttons return; } if (this.inactiveTabBkg == null) { this.inactiveTabBkg = new LinearGradientBrush(new Point(0, 0), new Point(0, e.Item.Height), SystemColors.Control, SystemColors.ControlDark); this.hoverTabBkg = new LinearGradientBrush(new Point(0, 0), new Point(0, e.Item.Height), SystemColors.ControlLight, SystemColors.Control); this.pressedTabBkg = new SolidBrush(SystemColors.ControlLight); } using (LinearGradientBrush activeTabBkg = new LinearGradientBrush(new Point(0, 0), new Point(0, e.Item.Height), SystemColors.ControlLight, this.GetActiveTabBtmCol(e.ToolStrip, e.Item))) { ToolStripButton button = (ToolStripButton)e.Item; Brush colour = this.inactiveTabBkg; if (button.Checked) { colour = activeTabBkg; if (OsUtils.Windows()) { // Invalidate between the buttons and the bottom of the toolstrip so that it gets repainted e.ToolStrip.Invalidate(new Rectangle(0, e.Item.Bounds.Bottom, e.ToolStrip.Bounds.Width, e.ToolStrip.Bounds.Height - e.Item.Bounds.Bottom)); } } else if (e.Item.Selected) { if (e.Item.Pressed) { colour = this.pressedTabBkg; } else { colour = this.hoverTabBkg; } } e.Graphics.SmoothingMode = SmoothingMode.HighQuality; int width = e.Item.Width - TabSeparation; int height = e.Item.Height; using (GraphicsPath tab = new GraphicsPath()) { tab.AddLine(0, height, 0, CurveSize); tab.AddArc(0, 0, CurveSize, CurveSize, 180, 90); tab.AddLine(CurveSize, 0, width - CurveSize, 0); tab.AddArc(width - CurveSize, 0, CurveSize, CurveSize, 270, 90); tab.AddLine(width, CurveSize, width, height); e.Graphics.FillPath(colour, tab); e.Graphics.DrawPath(this.tabBorder, tab); } } }
private void SearchBox_Resize(object sender, EventArgs e) { if (this.Height != this.themeHeight) { // Force the height to always be set to that specified from the theme this.Height = this.themeHeight; } // Vertically center the search / cancel button on the right hand side this.button.Left = this.Width - (this.button.Width + 6); this.button.Top = Convert.ToInt32((this.Height - this.button.Height) / 2) + 1; // Use the rest of the space for the textbox this.textBox.Top = 4; this.textBox.Width = this.button.Left - (this.textBox.Left + 4); if (OsUtils.WinVistaOrLater() && VisualStyleRenderer.IsSupported) { // The textbox is given extra padding as part of the visual style this.textBox.Left = 2; } else { this.textBox.Left = 6; } }
private void Status_FormClosing(object sender, FormClosingEventArgs e) { // Prevent closing under Windows via right-click taskbar menu // Mono sets e.CloseReason to UserClosing from a call to Hide() if (e.CloseReason == CloseReason.UserClosing && OsUtils.Windows()) { e.Cancel = true; } }
private void SetProgressBarValue_FormThread(int value) { this.Progress.Value = value; if (OsUtils.WinSevenOrLater() && this.IsHandleCreated) { this.tbarNotif.SetProgressValue(this, value, this.Progress.Maximum); } }
private void Status_Load(object sender, EventArgs e) { this.Font = SystemFonts.MessageBoxFont; if (OsUtils.WinSevenOrLater()) { this.tbarNotif = new TaskbarNotify(); } }
private void ExtendFrameIntoClientArea() { if (!OsUtils.CompositionEnabled()) { return; } Marshal.ThrowExceptionForHR(NativeMethods.DwmExtendFrameIntoClientArea(this.Handle, ref this.glassMargins)); }
private void SearchBox_HandleCreated(object sender, EventArgs e) { if (OsUtils.WinVistaOrLater()) { // Set the theme of this parent control and the edit control, so they are rendered correctly Marshal.ThrowExceptionForHR(NativeMethods.SetWindowTheme(this.Handle, "SearchBoxComposited", null)); Marshal.ThrowExceptionForHR(NativeMethods.SetWindowTheme(this.textBox.Handle, "SearchBoxEditComposited", null)); } }
private void ButtonReset_Click(object sender, EventArgs e) { if (Interaction.MsgBox("Are you sure that you would like to reset all of your settings?", MsgBoxStyle.YesNo | MsgBoxStyle.Question) == MsgBoxResult.Yes) { Settings.ResetUserSettings(); OsUtils.ApplyRunOnStartup(); this.Close(); } }
private void LinkUpdate_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { using (UpdateNotify showUpdate = new UpdateNotify()) { if (showUpdate.ShowDialog(this) == DialogResult.Yes) { OsUtils.LaunchUrl(new Uri("https://nerdoftheherd.com/tools/radiodld/"), "Download Update (About)"); this.Close(); } } }
private void SearchBox_Paint(object sender, System.Windows.Forms.PaintEventArgs e) { if (VisualStyleRenderer.IsSupported) { VisualStyleRenderer searchBoxStyle = null; if (OsUtils.WinVistaOrLater()) { // Fetch the correct style based on the current state searchBoxStyle = new VisualStyleRenderer(NativeMethods.SEARCHBOX, NativeMethods.SBBACKGROUND, this.boxState); } else { searchBoxStyle = new VisualStyleRenderer(VisualStyleElement.TextBox.TextEdit.Normal); } // Paint the visual style background for the control searchBoxStyle.DrawBackground(e.Graphics, new Rectangle(0, 0, this.Width, this.Height)); } else { // It would be simpler to use e.Graphics.Clear(SystemColors.Window), but that crashes // sometimes when running under terminal services due to a bug in GDI+ using (Brush windowBrush = new SolidBrush(SystemColors.Window)) { e.Graphics.FillRectangle(windowBrush, 0, 0, this.Width - 1, this.Height - 1); } // Paint a 'classic textbox' border for the control using (Pen controlDark = new Pen(SystemColors.ControlDark)) { using (Pen controlDarkDark = new Pen(SystemColors.ControlDarkDark)) { using (Pen controlLightLight = new Pen(SystemColors.ControlLightLight)) { using (Pen controlLight = new Pen(SystemColors.ControlLight)) { e.Graphics.DrawLine(controlDark, 0, this.Height, 0, 0); e.Graphics.DrawLine(controlDark, 0, 0, this.Width, 0); e.Graphics.DrawLine(controlDarkDark, 1, this.Height - 1, 1, 1); e.Graphics.DrawLine(controlDarkDark, 1, 1, this.Width - 1, 1); e.Graphics.DrawLine(controlLight, this.Width - 2, 1, this.Width - 2, this.Height - 2); e.Graphics.DrawLine(controlLight, this.Width - 2, this.Height - 2, 1, this.Height - 2); e.Graphics.DrawLine(controlLightLight, this.Width - 1, 0, this.Width - 1, this.Height - 1); e.Graphics.DrawLine(controlLightLight, this.Width - 1, this.Height - 1, 0, this.Height - 1); } } } } } }
public bool SendReport() { try { WebClient sendClient = new WebClient(); sendClient.Headers.Add("Content-Type", "application/x-www-form-urlencoded"); string postData = string.Empty; foreach (KeyValuePair <string, string> reportField in this.fields) { postData += "&" + HttpUtility.UrlEncode(reportField.Key) + "=" + HttpUtility.UrlEncode(reportField.Value); } postData = postData.Substring(1); byte[] result = sendClient.UploadData(SendReportUrl, "POST", System.Text.Encoding.ASCII.GetBytes(postData)); string[] returnLines = System.Text.Encoding.ASCII.GetString(result).Split('\n'); if (returnLines[0] == "success") { string successMessage = "Your error report was sent successfully."; if (returnLines.Length > 1) { int reportNum; if (int.TryParse(returnLines[1], NumberStyles.Integer, CultureInfo.InvariantCulture, out reportNum)) { successMessage += Environment.NewLine + Environment.NewLine + "The report number is " + reportNum.ToString(CultureInfo.CurrentCulture) + "."; } } MessageBox.Show(successMessage, Application.ProductName); Uri moreInfo; if (Uri.TryCreate(returnLines[1], UriKind.Absolute, out moreInfo)) { OsUtils.LaunchUrl(moreInfo, "Error Report"); } return(true); } } catch { // No way of reporting errors that have happened here, so just give up } return(false); }
protected override void OnCreateMainForm() { // If /exit was passed on the command line, then just exit immediately foreach (string commandLineArg in Environment.GetCommandLineArgs()) { if (commandLineArg.ToUpperInvariant() == "/EXIT") { Environment.Exit(1); } } if (!OsUtils.Windows()) { // Mono has a bug which causes the useDefaultCredentials attribute to be // treated as invalid, so clear the default proxy to prevent an exception WebRequest.DefaultWebProxy = null; } try { // Add TLS 1.1 and 1.2 to allowed protocols for HTTPS requests // Constants are not defined until .NET 4.5, so use the values ServicePointManager.SecurityProtocol |= (SecurityProtocolType)0x00000300 | // SecurityProtocolType.Tls11 (SecurityProtocolType)0x00000C00; // SecurityProtocolType.Tls12 } catch (NotSupportedException) { if (OsUtils.Windows()) { MessageBox.Show( "The .NET framework needs an update (to enable TLS 1.1 and 1.2) before Radio Downloader can run." + Environment.NewLine + Environment.NewLine + "Please check for available updates and install all of those which relate to the .NET framework.", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Stop); Environment.Exit(1); } throw; } // Set up the application database and perform any required updates or cleanup if (!DatabaseInit.Startup()) { Environment.Exit(1); } this.MainForm = new Main(); this.StartupNextInstance += ((Main)this.MainForm).App_StartupNextInstance; }
private void SetProgressBarMarquee_FormThread(bool marquee) { this.Progress.Style = marquee ? ProgressBarStyle.Marquee : ProgressBarStyle.Blocks; if (OsUtils.WinSevenOrLater() && this.IsHandleCreated) { if (marquee) { this.tbarNotif.SetProgressMarquee(this); } else { this.tbarNotif.SetProgressNone(this); } } }
public SearchBox() : base() { this.TextChanged += this.SearchBox_TextChanged; this.Resize += this.SearchBox_Resize; this.Paint += this.SearchBox_Paint; this.HandleCreated += this.SearchBox_HandleCreated; this.SetStyle(ControlStyles.SupportsTransparentBackColor, true); // Create the child textbox control for the user to type in, without a border this.textBox = new TextBox(); this.themeHeight = this.textBox.Height + 2; this.textBox.BorderStyle = BorderStyle.None; this.Controls.Add(this.textBox); this.textBox.MouseEnter += this.TextBox_MouseEnter; this.textBox.MouseLeave += this.TextBox_MouseLeave; this.textBox.GotFocus += this.TextBox_GotFocus; this.textBox.LostFocus += this.TextBox_LostFocus; this.textBox.TextChanged += this.TextBox_TextChanged; this.textBox.KeyDown += this.TextBox_KeyDown; // Create a picturebox to display the search icon and cancel 'button' this.button = new PictureBox(); this.button.BackColor = Color.Transparent; this.button.Image = Properties.Resources.search_icon; this.button.SizeMode = PictureBoxSizeMode.AutoSize; this.Controls.Add(this.button); this.button.MouseEnter += this.Button_MouseEnter; this.button.MouseLeave += this.Button_MouseLeave; this.button.MouseDown += this.Button_MouseDown; this.button.MouseUp += this.Button_MouseUp; this.button.MouseClick += this.Button_MouseClick; // Work out the height that the search box should be displayed if (OsUtils.WinVistaOrLater() && VisualStyleRenderer.IsSupported) { VisualStyleRenderer sizeStyle = new VisualStyleRenderer(NativeMethods.SEARCHBOX, NativeMethods.SBBACKGROUND, NativeMethods.SBB_NORMAL); using (Graphics sizeGraphics = this.CreateGraphics()) { this.themeHeight = sizeStyle.GetPartSize(sizeGraphics, ThemeSizeType.True).Height; } } }
private void Status_Shown(object sender, EventArgs e) { if (OsUtils.WinSevenOrLater()) { if (this.Progress.Style == ProgressBarStyle.Marquee) { this.tbarNotif.SetProgressMarquee(this); } else { if (this.Progress.Value != 0) { this.tbarNotif.SetProgressValue(this, this.Progress.Value, this.Progress.Maximum); } } } this.workThread = new Thread(this.WorkThread); this.workThread.Start(); }
protected override void OnRenderToolStripBorder(ToolStripRenderEventArgs e) { if (OsUtils.WinVistaOrLater() && VisualStyleRenderer.IsSupported) { if (!OsUtils.CompositionEnabled()) { e.Graphics.DrawLine(this.nonAeroBorder, 0, e.AffectedBounds.Bottom - 1, e.ToolStrip.Width, e.AffectedBounds.Bottom - 1); } } else { e.Graphics.DrawLine(this.tabBorder, 0, e.AffectedBounds.Bottom - 1, e.ToolStrip.Width, e.AffectedBounds.Bottom - 1); } ToolStripButton @checked = null; // Find the currently checked ToolStripButton foreach (ToolStripItem item in e.ToolStrip.Items) { ToolStripButton buttonItem = item as ToolStripButton; if (buttonItem != null && buttonItem.Checked) { @checked = buttonItem; break; } } if (@checked != null) { // Extend the bottom of the tab over the client area border, joining the tab onto the main client area using (SolidBrush toolbarBkg = new SolidBrush(this.GetActiveTabBtmCol(e.ToolStrip, @checked))) { e.Graphics.FillRectangle(toolbarBkg, new Rectangle(@checked.Bounds.Left, @checked.Bounds.Bottom, @checked.Bounds.Width - TabSeparation, e.ToolStrip.Bounds.Bottom - @checked.Bounds.Bottom)); } e.Graphics.DrawLine(this.tabBorder, @checked.Bounds.Left, @checked.Bounds.Bottom, @checked.Bounds.Left, e.AffectedBounds.Bottom); e.Graphics.DrawLine(this.tabBorder, @checked.Bounds.Right - TabSeparation, @checked.Bounds.Bottom, @checked.Bounds.Right - TabSeparation, e.AffectedBounds.Bottom); } }
public TaskbarNotify() { if (!OsUtils.Windows()) { // OS doesn't support ITaskbarList3 interface return; } this.taskBarListInst = (NativeMethods.ITaskbarList3) new TaskbarList(); try { this.taskBarListInst.HrInit(); } catch (NotImplementedException) { // Some third party Windows shells don't support ITaskbarList3 return; } this.Supported = true; }
/// <summary> /// Handle the WM_SETCURSOR message and set the correct system link cursor. /// </summary> /// <param name="m">The Windows <see cref="Message" /> to process.</param> protected override void WndProc(ref Message m) { if (OsUtils.Windows() && m.Msg == NativeMethods.WM_SETCURSOR) { // Fetch a handle to the system 'hand' cursor. IntPtr cursor = NativeMethods.LoadCursor(IntPtr.Zero, (IntPtr)NativeMethods.IDC_HAND); // NULL cursor if (cursor == IntPtr.Zero) { throw new Win32Exception(); } // Set this control's cursor to the 'hand' NativeMethods.SetCursor(cursor); // Show that the message has been handled successfully m.Result = IntPtr.Zero; return; } base.WndProc(ref m); }
protected override void OnRenderToolStripBackground(ToolStripRenderEventArgs e) { if (OsUtils.CompositionEnabled()) { // Set the background colour to transparent to make it glass e.Graphics.Clear(Color.Transparent); } else { if (VisualStyleRenderer.IsSupported && OsUtils.WinVistaOrLater()) { // Set the background the same as the title bar to give the illusion of an extended frame if (this.isActive) { // It would be simpler to use e.Graphics.Clear(SystemColors.GradientActiveCaption), but // that crashes sometimes when running under terminal services due to a bug in GDI+ using (Brush backgroundBrush = new SolidBrush(SystemColors.GradientActiveCaption)) { e.Graphics.FillRectangle(backgroundBrush, e.AffectedBounds); } } else { // It would be simpler to use e.Graphics.Clear(SystemColors.GradientInactiveCaption), but // that crashes sometimes when running under terminal services due to a bug in GDI+ using (Brush backgroundBrush = new SolidBrush(SystemColors.GradientInactiveCaption)) { e.Graphics.FillRectangle(backgroundBrush, e.AffectedBounds); } } } else { base.OnRenderToolStripBackground(e); } } }
private void DownloadProgThread() { // Raise a progress event to give the user some feedback this.Progress?.Invoke(this.episodeInfo.Epid, 0, Provider.ProgressType.Downloading); if (!Provider.Handler.Exists(this.pluginId)) { this.DownloadError(Provider.ErrorType.LocalProblem, "The plugin provider required to download this episode is not currently available. Please try updating the Radio Downloader providers or cancelling the download."); return; } lock (this.pluginInstanceLock) { this.pluginInstance = Provider.Handler.GetFromId(this.pluginId).CreateInstance(); this.pluginInstance.Progress += this.DownloadPluginInst_Progress; } string saveLocation; try { saveLocation = FileUtils.GetSaveFolder(); } catch (DirectoryNotFoundException) { this.DownloadError(Provider.ErrorType.LocalProblem, "Your chosen location for saving downloaded programmes no longer exists. Select a new one under Options -> Main Options."); return; } const int FreeMb = 250; ulong availableSpace = OsUtils.PathAvailableSpace(saveLocation); if (availableSpace <= FreeMb * 1024 * 1024) { this.DownloadError(Provider.ErrorType.LocalProblem, "Your chosen location for saving downloaded programmes does not have enough free space. Make sure that you have at least " + FreeMb.ToString(CultureInfo.CurrentCulture) + " MB free, or select a new location under Options -> Main Options."); return; } Provider.DownloadInfo info = null; try { try { info = this.pluginInstance.DownloadProgramme(this.progExtId, this.episodeExtId, this.providerProgInfo, this.providerEpisodeInfo); } catch (Provider.DownloadException downloadExp) { if (downloadExp.ErrorType == Provider.ErrorType.UnknownError) { this.DownloadError(downloadExp); } else { this.DownloadError(downloadExp.ErrorType, downloadExp.Message); } return; } catch (Exception unknownExp) { this.DownloadError(unknownExp); return; } if (this.cancelled) { this.cancelResponse = true; return; } string finalName; try { finalName = Model.Download.MoveToSaveFolder(Settings.FileNameFormat, this.progInfo, this.episodeInfo, saveLocation, info.Extension, info.Downloaded.FilePath); } catch (IOException ioExp) { this.DownloadError(Provider.ErrorType.LocalProblem, "Encountered an error saving the downloaded file. " + ioExp.Message + " You may need to select a new location for saving downloaded programmes under Options -> Main Options."); return; } catch (UnauthorizedAccessException unAuthExp) { this.DownloadError(Provider.ErrorType.LocalProblem, "Encountered a permissions problem saving the downloaded file. " + unAuthExp.Message + " You may need to select a new location for saving downloaded programmes under Options -> Main Options."); return; } lock (DbUpdateLock) { Model.Download.SetComplete(this.episodeInfo.Epid, finalName, info); Model.Programme.SetLatestDownload(this.progInfo.Progid, this.episodeInfo.Date); } // Remove single episode subscriptions if (Model.Subscription.IsSubscribed(this.progInfo.Progid)) { if (this.progInfo.SingleEpisode) { Model.Subscription.Remove(this.progInfo.Progid); } } if (!string.IsNullOrEmpty(Settings.RunAfterCommand)) { try { // Use VB Interaction.Shell as Process.Start doesn't give the option of a non-focused window // The "comspec" environment variable gives the path to cmd.exe Microsoft.VisualBasic.Interaction.Shell("\"" + Environment.GetEnvironmentVariable("comspec") + "\" /c " + Settings.RunAfterCommand.Replace("%file%", finalName), Microsoft.VisualBasic.AppWinStyle.NormalNoFocus); } catch { // Just ignore the error, as it just means that something has gone wrong with the run after command. } } } finally { info?.Dispose(); } this.DownloadFinished(); }
private void ShowHelp() { OsUtils.LaunchUrl(new Uri("http://www.nerdoftheherd.com/tools/radiodld/help/dialogs.options/"), "Context Help"); }
protected override void OnRenderItemText(ToolStripItemTextRenderEventArgs e) { if (!OsUtils.CompositionEnabled()) { // The OS doesn't support desktop composition, or it isn't enabled base.OnRenderItemText(e); return; } // Drawing text on glass is a bit of a pain - text generated with GDI (e.g. standard // controls) ends up being transparent as GDI doesn't understand alpha transparency. // GDI+ is fine drawing text on glass but it doesn't use ClearType, so the text ends // up looking out of place, ugly or both. The proper way is using DrawThemeTextEx, // which works fine, but requires a top-down DIB to draw to, rather than the bottom // up ones that GDI normally uses. Hence; create top-down DIB, draw text to it and // then AlphaBlend it in to the graphics object that we are rendering to. // Get the rendering HDC, and create a compatible one for drawing the text to IntPtr renderHdc = e.Graphics.GetHdc(); IntPtr memoryHdc = NativeMethods.CreateCompatibleDC(renderHdc); // NULL Pointer if (memoryHdc == IntPtr.Zero) { throw new Win32Exception(); } NativeMethods.BITMAPINFO info = default(NativeMethods.BITMAPINFO); info.biSize = Convert.ToUInt32(Marshal.SizeOf(typeof(NativeMethods.BITMAPINFO))); info.biWidth = e.TextRectangle.Width; info.biHeight = -e.TextRectangle.Height; // Negative = top-down info.biPlanes = 1; info.biBitCount = 32; info.biCompression = NativeMethods.BI_RGB; IntPtr bits = IntPtr.Zero; // Create the top-down DIB IntPtr dib = NativeMethods.CreateDIBSection(renderHdc, ref info, 0, ref bits, IntPtr.Zero, 0); // NULL Pointer if (dib == IntPtr.Zero) { throw new Win32Exception(); } // Select the created DIB into our memory DC for use // NULL Pointer if (NativeMethods.SelectObject(memoryHdc, dib) == IntPtr.Zero) { throw new Win32Exception(); } // Create a font we can use with GetThemeTextEx IntPtr hFont = e.TextFont.ToHfont(); // And select it into the DC as well // NULL Pointer if (NativeMethods.SelectObject(memoryHdc, hFont) == IntPtr.Zero) { throw new Win32Exception(); } // Fetch a VisualStyleRenderer suitable for toolbar text VisualStyleRenderer renderer = new VisualStyleRenderer(VisualStyleElement.ToolBar.Button.Normal); // Set up a RECT for the area to draw the text in NativeMethods.RECT textRect = default(NativeMethods.RECT); textRect.left = 0; textRect.top = 0; textRect.right = e.TextRectangle.Width; textRect.bottom = e.TextRectangle.Height; // Options for GetThemeTextEx NativeMethods.DTTOPTS opts = default(NativeMethods.DTTOPTS); opts.dwSize = Convert.ToUInt32(Marshal.SizeOf(opts)); opts.dwFlags = NativeMethods.DTT_COMPOSITED | NativeMethods.DTT_TEXTCOLOR; opts.crText = Convert.ToUInt32(ColorTranslator.ToWin32(e.TextColor)); // Alpha blended text of the colour specified // Paint the text Marshal.ThrowExceptionForHR(NativeMethods.DrawThemeTextEx(renderer.Handle, memoryHdc, 0, 0, e.Text, -1, (uint)e.TextFormat, ref textRect, ref opts)); // Set up the AlphaBlend copy NativeMethods.BLENDFUNCTION blendFunc = default(NativeMethods.BLENDFUNCTION); blendFunc.BlendOp = NativeMethods.AC_SRC_OVER; blendFunc.SourceConstantAlpha = 255; blendFunc.AlphaFormat = NativeMethods.AC_SRC_ALPHA; // Per-pixel alpha only // Blend the painted text into the render DC if (!NativeMethods.AlphaBlend(renderHdc, e.TextRectangle.Left, e.TextRectangle.Top, e.TextRectangle.Width, e.TextRectangle.Height, memoryHdc, 0, 0, e.TextRectangle.Width, e.TextRectangle.Height, blendFunc)) { throw new Win32Exception(); } // Clean up the GDI objects if (!NativeMethods.DeleteObject(hFont)) { throw new Win32Exception(); } if (!NativeMethods.DeleteObject(dib)) { throw new Win32Exception(); } if (!NativeMethods.DeleteDC(memoryHdc)) { throw new Win32Exception(); } e.Graphics.ReleaseHdc(); }
public static bool Startup() { const string DbFileName = "store.db"; string specDbPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, DbFileName); string appDbPath = Path.Combine(FileUtils.GetAppDataFolder(), DbFileName); // Ensure that the template database exists if (!File.Exists(specDbPath)) { MessageBox.Show("The Radio Downloader template database was not found at '" + specDbPath + "'." + Environment.NewLine + Environment.NewLine + "Try repairing the Radio Downloader installation or installing the latest version from nerdoftheherd.com", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Stop); return(false); } using (SQLiteConnection specConn = new SQLiteConnection("Data Source=" + specDbPath + ";Version=3;New=False;Read Only=True")) { specConn.Open(); using (SQLiteCommand command = new SQLiteCommand("pragma integrity_check(1)", specConn)) { string result = (string)command.ExecuteScalar(); if (result.ToUpperInvariant() != "OK") { MessageBox.Show("The Radio Downloader template database at '" + specDbPath + "' appears to be corrupted." + Environment.NewLine + Environment.NewLine + "Try repairing the Radio Downloader installation or installing the latest version from nerdoftheherd.com", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Stop); return(false); } } // Migrate old (pre 0.26) version databases from www.nerdoftheherd.com -> NerdoftheHerd.com string oldDbPath = Path.Combine(Path.Combine(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "www.nerdoftheherd.com"), Application.ProductName), DbFileName); if (File.Exists(oldDbPath) && !File.Exists(appDbPath)) { File.Move(oldDbPath, appDbPath); } // Test if there is an existing application database if (!File.Exists(appDbPath)) { // Start with a copy of the template database File.Copy(specDbPath, appDbPath); // Set the current database version in the new database Settings.DatabaseVersion = Database.CurrentDbVersion; } else { using (SQLiteCommand command = new SQLiteCommand("pragma integrity_check(1)", FetchDbConn())) { string result = (string)command.ExecuteScalar(); if (result.ToUpperInvariant() != "OK") { if (MessageBox.Show("Unfortunately Radio Downloader cannot start because your database has become corrupted." + Environment.NewLine + Environment.NewLine + "Would you like to view some help about resolving this issue?", Application.ProductName, MessageBoxButtons.YesNo, MessageBoxIcon.Stop) == DialogResult.Yes) { OsUtils.LaunchUrl(new Uri("https://nerdoftheherd.com/tools/radiodld/help/corrupt-database"), "corruptdb"); } return(false); } } // Start a transaction so we can roll back a half-completed upgrade on error using (SQLiteMonTransaction transMon = new SQLiteMonTransaction(FetchDbConn().BeginTransaction())) { try { // Perform a check and automatic update of the database table structure UpdateStructure(specConn, Database.FetchDbConn()); // Perform any updates required which were not handled by UpdateStructure switch (Settings.DatabaseVersion) { case 4: // Clear error details previously serialised as XML using (SQLiteCommand command = new SQLiteCommand("update downloads set errordetails=null where errortype=@errortype", FetchDbConn())) { command.Parameters.Add(new SQLiteParameter("errortype", ErrorType.UnknownError)); command.ExecuteNonQuery(); } break; case Database.CurrentDbVersion: // Nothing to do, this is the current version. break; } // Set the current database version Settings.DatabaseVersion = Database.CurrentDbVersion; } catch (SQLiteException) { transMon.Trans.Rollback(); throw; } transMon.Trans.Commit(); } } } // Prune the database once a week if (Settings.LastPrune.AddDays(7) < DateTime.Now) { using (Status status = new Status()) { status.ShowDialog(delegate { Prune(status); }); } } // Vacuum the database every three months if (Settings.LastVacuum.AddMonths(3) < DateTime.Now) { using (Status status = new Status()) { status.ShowDialog(delegate { Vacuum(status); }); } } return(true); }
protected override void WndProc(ref Message m) { switch (m.Msg) { case NativeMethods.WM_CREATE: if (OsUtils.WinXpOrLater()) { // Set the theme of the control to "explorer", to give the // correct styling under Vista. This has no effect under XP. Marshal.ThrowExceptionForHR(NativeMethods.SetWindowTheme(this.Handle, "explorer", null)); } // Remove the focus rectangle from the control (and as a side effect, all other controls on the // form) if the last input event came from the mouse, or add them if it came from the keyboard. NativeMethods.SendMessage(this.Handle, NativeMethods.WM_CHANGEUISTATE, this.MakeLParam(NativeMethods.UIS_INITIALIZE, NativeMethods.UISF_HIDEFOCUS), IntPtr.Zero); break; case NativeMethods.LVM_SETEXTENDEDLISTVIEWSTYLE: if (OsUtils.WinXpOrLater()) { int styles = (int)m.LParam; if ((styles & NativeMethods.LVS_EX_DOUBLEBUFFER) != NativeMethods.LVS_EX_DOUBLEBUFFER) { styles = styles | NativeMethods.LVS_EX_DOUBLEBUFFER; m.LParam = (IntPtr)styles; } } break; case NativeMethods.WM_SETFOCUS: // Remove the focus rectangle from the control (and as a side effect, all other controls on the // form) if the last input event came from the mouse, or add them if it came from the keyboard. NativeMethods.SendMessage(this.Handle, NativeMethods.WM_CHANGEUISTATE, this.MakeLParam(NativeMethods.UIS_INITIALIZE, NativeMethods.UISF_HIDEFOCUS), IntPtr.Zero); break; case NativeMethods.WM_NOTIFY: // Test to see if the notification was for a right-click in the header if (((NativeMethods.NMHDR)m.GetLParam(typeof(NativeMethods.NMHDR))).code == NativeMethods.NM_RCLICK) { // Fire an event to indicate the click has occurred. Set the column number // to -1 for all clicks, as this information isn't currently required. if (this.ColumnRightClick != null) { this.ColumnRightClick(this, new ColumnClickEventArgs(-1)); } } break; case NativeMethods.WM_PAINT: if (this.View != View.Details) { break; } // Calculate the position of all embedded controls foreach (KeyValuePair <ListViewItem, EmbeddedProgress> embedded in this.embeddedInfo) { Rectangle rect = this.GetSubItemBounds(embedded.Key, embedded.Value.Column); if (((this.HeaderStyle != ColumnHeaderStyle.None) && (rect.Top < this.Font.Height)) || (rect.Top + rect.Height) <= 0 || (rect.Top > this.ClientRectangle.Height)) { // Control overlaps ColumnHeader, is off the top, or is off the bottom of the listview embedded.Value.Progress.Visible = false; continue; } else { embedded.Value.Progress.Visible = true; } // Set embedded control's bounds embedded.Value.Progress.Bounds = rect; } break; } base.WndProc(ref m); }
private void LinkHomepage_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { OsUtils.LaunchUrl(new Uri(this.LinkHomepage.Text), "About Dialog Link"); }
private void ShowHelp() { OsUtils.LaunchUrl(new Uri("https://nerdoftheherd.com/tools/radiodld/help/dialogs.clean-up-downloads/"), "Context Help"); }