I have three versions, all have Source code and Application only downloads.
============================================
Updated to v1.3. Appearance changed, new improvements and bugfixes (See History at bottom for changes).
I hope you'll enjoy the new version!
Introduction
Having a few more weeks of C# experience and some new updates for this NFO Viewer, I once again updated this article. I'm running Windows 7 Ultimate x64, .NET 4.0 and I use Microsoft Visual Studio 2010.
This application has a custom 'Form', Functions to close application and mute music, custom icon, picture that goes to a website if you click it and the main thing is the richTextBox. In this box I will load the NFO file (text), which will be presented in custom colors, scrolls down automatically and loops, and a last thing: you can't interact with the text. It has to be presented like the end credits of a movie!
Using this article you can pick any part of code to create your own viewer or use the source to create a custom Viewer of the one provided here.
Background
I had a lot of NFO files, which I had to set 'open with notepad' to show them. Notepad doesn't show all correct symbols by default and doesn't position everything in the right place. Eventually I got some NFO Viewer samples that ran instantly and had a lot of custom things. I wanted that too, but couldn't change those files. So I decided to create them myself!
The Application + Options
Since this is a new update, some buttons/functions are different. I'll leave the old options as is, so people can still use those as well. Changes since 1.3: No close button (2) anymore (press Escape instead), Test Speedbuttons removed (7), changed speed options (1x +, 1x - instead of both 2x).
Picture 'Argaï NFO Viewer v1.1'
The above application contains the following parts:
- The mainframe (Windows
Form, without border);
I've used a big picture and set the Transparency option to White, to remove all around the actual picture. With a small piece of code, you can make the picture drag the whole application around.
A Button (X) to close the application once you run it;
- A
checkBox which will pause (mute) the music (mod format[.it/.xm/.s3m/.mod]) when it is unchecked;
- (Left side) A
pictureBox that you can click on. It will open the default user's webbrowser and go to my link;
- The most important one for this app: The
richTextBox!
This opens a specified .nfo file, converts it before presenting, load all the text and uses my edited autoscroll code to keep the text going up with a specific speed all the time. When it reaches the end, it will go back to the start and loop the scrolling. I didn't want a scroller, so I decided to 'hide' it. I also disabled all possible interactions with it.
- Another
pictureBox, that is disabled. This means you can't interact with any event, but you can click on it and drag the application around, like the image of the 'form'.
Extra
Buttons/KeyPress Events for Speed Options: Pause, Slower, Faster {Limited}
- Custom
Icon.
PictureBox as Button(Click Event) that opens 'About' Window.
- Music (mod format) in background that runs with application. [Needs an external Player]
- Additional Settings [Form Name, process name/description etc.]
Using the code
NOTE: As I've changed a lot in v1.3, not all code will be placed in this article. If you want to check some specific code, use the provided source code.
Let's try to explain how to make those individual parts with the specific options I wanted. You can change whatever you want to your own liking, but I wanted to create it this way and it was hard to find around the internet. At first, my application has imported all that's stated below:
using System; using System.Diagnostics; using System.Drawing; using System.Windows.Forms; using IrrKlang; .
using System.Reflection; using System.Runtime.InteropServices; using System.IO; using Un4seen.Bass;
1) The FORM [MAINFRAME]
Form properties:
Backgroundimage: to create the custom picture form.
BackgroundImageLayout: None (make your white area of the picture big enough, don't repeat the image).
DoubleBuffered: True, this prevents the application from flickering when dragging out of screen.
Icon: Chose the icon for the application WHEN IT IS RUNNING (format .ico), not for the .exe itself. If you want the white to be transparent, use some software that can delete the unwanted are and save it as a transparent image (e.g. Paint.net). I used http://converticon.com/ to create the icon of my image.
Size: you can manually set your size here, but in your Design View you can change it by dragging the borders.
StartPosition: CenterScreen, this will open the application in the center of your screen.
Text: Here you can set the text you want to appear above the Taskbar Icon of the running application.
TransparencyKey: White, depends on the background color you want to remove of your selected picture.
We want to be able to move around our program.
To do this, create 2 new Events for the form and name them wisely, or double click the field and use the default names. In my application I always use the default ones.
In the Properties window, select the lightning icon (Events).
MouseDown: Form1_MouseDown
MouseMove: Form1_MouseMove
This will create two new methods to do something when these events happen on your picture (form). Add the following code to the methods in your form:
public Point mouse_offset;
private void Form1_MouseDown(object sender,
System.Windows.Forms.MouseEventArgs e)
{
mouse_offset = new Point(-e.X, -e.Y);
}
private void Form1_MouseMove(object sender,
System.Windows.Forms.MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
Point mousePos = Control.MousePosition;
mousePos.Offset(mouse_offset.X, mouse_offset.Y);
Location = mousePos;
}
}
There was a 'bug', if users pressed Arrow Keys, they would enter the richTextBox (focus changes) and using the Arrow Keys and PageUp/Pagedown Keys they could navigate in it. I've searched and found working code to disable this. I also added the Escape key function here, as Escape is a Command key. Now you can Close the application by pressing Escape when the application is active.
In the Form_Load( ) method, add:
foreach (Control control in this.Controls)
{
control.PreviewKeyDown += new PreviewKeyDownEventHandler(control_PreviewKeyDown);
}
Outside of this method, add another method with following code:
void control_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{ if (e.KeyCode == Keys.Up || e.KeyCode == Keys.Down || e.KeyCode == Keys.Left || e.KeyCode == Keys.Right)
{ e.IsInputKey = true; }
if (e.KeyCode == Keys.Escape)
{ this.Close(); }
}
When this code is added, you won't be able to switch from the Form to the richTextBox using arrow Keys.
I also added a Fade Effect of music and app when the application closes.
This effect is triggered when the application gets a message that it needs to close.
The following code handles the effect of the appearance, and also fades the music with it. I used timers to fade away with different speeds. You can combine it and change speed if it fits, do as you want.
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (this.Opacity > 0.01f)
{
e.Cancel = true;
Bass.BASS_SetConfig(BASSConfig.BASS_CONFIG_GVOL_MUSIC, 7000);
AppFadeTimer.Interval = 33;
VolFadeTimer.Interval = 10;
AppFadeTimer.Enabled = true;
VolFadeTimer.Enabled = true;
}
else
{ AppFadeTimer.Enabled = false; VolFadeTimer.Enabled = false; }
}
private void AppFadeTimer_Tick(object sender, EventArgs e)
{
if (this.Opacity > 0.01)
{ this.Opacity = this.Opacity - 0.01f; }
else
{
this.Close();
}
}
private void VolFadeTimer_Tick(object sender, EventArgs e)
{ vol = vol - 26; Bass.BASS_SetConfig(BASSConfig.BASS_CONFIG_GVOL_MUSIC, vol);}
As I make different app designs and versions, this may differ a lot, but it works.
2) The BUTTON [Close Application]
Button Properties:
Text: Change it to something that says: 'close me'.
Cursor: I changed this to Hand, so you can better see it's clickable.
BackColor and ForeColor: Change the color style of button and text.
Size and Location: Drag around and resize in Design mode, or type the numbers.
We want to be able to close our program with a X-Button.
In Design Mode, add a Button from the Toolbox, change the Property Text to 'X' or 'Close' and size it to your liking. Add the Event Click: 'button1_Click'. This will create a method for the Event to do something when the user presses the button.
Use the following code to close the application:
private void button1_Click(object sender, System.EventArgs e)
{
this.Close();
}
3) The CHECKBOX [Pause Music]
checkBox Properties:
BackColor: I've set this one Transparent, to see only the box, and the text has no white background then.
Checked: I want my music ON default, so this one is True when the application starts.
CheckState: I want a check in my box, you can also disable the box (gray), but here it's active: Checked.
Cursor: Hand.
ForeColor: LawnGreen in my example, or change it to any color you want.
Text: Type the text that will be next to the checkBox, in my case: Music?
Size and Location: Drag around and resize in Design mode, or type the numbers.
We want to be able to mute the music (pause) with a checkBox.
In Design Mode, add a checkBox to the form. Change the properties like the example above or to your own desire. Now we go set the checkBox' event. We simulate that people turn of our check, to disable the music. Add the Event CheckChanged: checkBox2_CheckedChange. Now you have the method for this event.
Add the code to pause or stop the music. In my case, I use irrKlang modplayer BASS to play the mod music files. To see how I implemented this, see 10) Music (.it format) To pause this music in irrKlang BASS, add the following code in the checkBox2_CheckChange method:
private void checkBox2_CheckedChange(object sender, EventArgs e)
{
CheckState state = checkBox2.CheckState; if (state == CheckState.Checked) {
engine.SetAllSoundsPaused(false); }
else {
engine.SetAllSoundsPaused(true); }
}
private void checkBox2_CheckedChange(object sender, EventArgs e)
{
CheckState state = checkBox2.CheckState;
if (state == CheckState.Checked)
{ Bass.BASS_Start(); }
else
{ Bass.BASS_Pause(); }
}
4) The PICTUREBOX [Clickable]
pictureBox Properties:
BackgroundImage: Select the image you want to show.
BorderStyle: I changed this to FixedSingle; seperate the dark image from the black richTextBox background.
Cursor: I changed this to AppStarting (just for fun, to show you can click).
Size and Location: Drag around and resize in Design mode, or type the numbers.
We want to be able to go to a website by clicking on an image. Besides, don't pick Internet Explorer, but the default browser of the client system. In Design Mode, add a pictureBox to the form. Change the Properties like the example above or to your own desire. Now we add the Event from the Properties' Event window: Click, e.g. pictureBox1_Click.
In the method that we just created add:
private void pictureBox1_Click(object sender, EventArgs e)
{
Process myProcess = new Process();
{
myProcess.StartInfo.UseShellExecute = true; myProcess.StartInfo.FileName = "http://tehparadox.com/forum/f73/arga-prophecy-2001-dutch-2631589/";
myProcess.Start(); }
}
5) The RICHTEXTBOX [Autoscroll locked NFO viewer]
richTextBox properties:
BackColor: In my example set to MenuText (black).
BorderStyle: None, as I want to cut of any edges and the scrollbar in my scroll.
Cursor: default is IBeam, but I don't want to select text! Set Arrow or Default (pointer).
DetectUrls: False, I just want to present the text and I have ASCii art which contains invalid 'links'...
Font: If you use ASCii art, this one is important, there are just a few fonts that support that. I've chosen Courier New for my application.
ForeColor: LawnGreen in my example, or change it to any color you want.
ReadOnly: True, I don't want to change the presented text, in any way.
ScrollBars: I wanted this set None, but to get my scrolling working, it needs the scrollbar, so I set Both.
Size and Location: Drag around and resize in Design mode, or type the numbers.
We want to be able to view a .nfo file correctly in the richTextBox. In Design mode, add a richTextBox to the form. Change the Properties like the example above or to your own desire. If you don't have the Load event from the Form already, create one (e.g. Form1_Load). When the Form and all components are loaded, we want to check if the .nfo file exists. When it does, convert it to the right format and present it, otherwise put the text 'NFO not found' in the richTextBox.
Final code (this just shows the text in the box, no scrolling yet):
private void Form1_Load(object sender, EventArgs e)
{
string file_name = "C:\\Test\\DARTY.nfo";
if (System.IO.File.Exists(file_name) == true) {
System.Text.Encoding encoding = System.Text.Encoding.GetEncoding(437);
System.IO.StreamReader file = new System.IO.StreamReader(file_name, encoding);
richTextBox1.Text = file.ReadToEnd();
file.Close();
}
else {
richTextBox1.Text = "File not Found! :( --- Where is DARTY.nfo??";
}
}
OR we can use a .nfo file as a resource, which will be better in this case.
To do this, open the project properties and select the 'Resources' tab. Add an existing file (our .nfo file)
and view the properties. We need to change the FileType to Text and then another option appears:
Encoding. Set this to OEM United States - Codepage 437. If those options aren't available, try to change the View to 'View Details' instead of View In List or View As Thumbnails (Just like on computer).
When this is set, we don't have to check existence and don't have to read and encode the file anymore.
This will leave the following short code as final result:
string file_name = Properties.Resources.Eng_Dut_01; richTextBox1.Text = file_name;
The variable 'file_name' will be directed to the resource we've added and the Text of the richTextBox will be filled with the resource data. We don't need the lines from the previous part anymore to work through the file!
We want to be able to disable all interaction with the richTextBox, without disabling the box itself. Disabling the richTextBox is almost all right, but it prevents us from selecting custom colors! I've created a new Form with the same size and location as the richTextBox. Opacity 1% so you can't see it and it moves around with the application as well. This prevents any interaction with our richTextBox, just as we wanted!
If you want to see the code, use my source code (v1.3).
We want to be able to autoscroll the richTextBox and loop it, to view all the text like movie credits.
Prepare, as this code isn't easy at all. You don't have an option to just automatically scroll a box at a specified speed. There is a code option however to go up line by line, but that isn't easy to read. See it this way: We need a Messageservice from a dll, to tell the richTextBox to move up a pixel each few milliseconds. So we set up the task (moving up) and have to create a timer, that sends the task as a message every few milliseconds we have set before.
I didn't get all of the code, but it worked! See REFERENCES at the bottom for the project I got this from. The only thing I changed was the speed of scrolling + options to adjust that, it goes back to start when it reaches the end (loop) and I changed the color before the text updates to a new location. This was hard as I needed to sync it with the different scrollingspeeds.
Import DLLs, create all references for the code
The following code (except first 'using' line) is placed between the public partial class and public Form1( )
using System.Runtime.InteropServices;
public partial class Form1 : Form
{
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool GetScrollInfo(IntPtr hwnd, int fnBar, ref SCROLLINFO lpsi);
[DllImport("user32.dll")]
static extern int SetScrollInfo(IntPtr hwnd, int fnBar, [In] ref SCROLLINFO lpsi, bool fRedraw);
[DllImport("User32.dll", CharSet = CharSet.Auto, EntryPoint = "SendMessage")]
static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
struct SCROLLINFO {
public uint cbSize;
public uint fMask;
public int nMin;
public int nMax;
public uint nPage;
public int nPos;
public int nTrackPos;
}
enum ScrollBarDirection
{
SB_HORZ = 0,
SB_VERT = 1,
SB_CTL = 2,
SB_BOTH = 3
}
enum ScrollInfoMask
{
SIF_RANGE = 0x1,
SIF_PAGE = 0x2,
SIF_POS = 0x4,
SIF_DISABLENOSCROLL = 0x8,
SIF_TRACKPOS = 0x10,
SIF_ALL = SIF_RANGE + SIF_PAGE + SIF_POS + SIF_TRACKPOS
}
const int WM_VSCROLL = 277;
const int SB_LINEUP = 0;
const int SB_LINEDOWN = 1;
const int SB_THUMBPOSITION = 4;
const int SB_THUMBTRACK = 5;
const int SB_TOP = 6;
const int SB_BOTTOM = 7;
const int SB_ENDSCROLL = 8;
private Timer t = new Timer();
Set the speed and enable Timer to send messages.
Add this code in the public Form1( )
public Form1()
{
InitializeComponent();
t.Interval = 40;
t.Tick += new EventHandler(t_Tick);
t.Enabled = true; }
Almost there, last bit of code for the autoscroll! Create the 2 methods t_Tick( ) and scroll( ) to run the process. I've added additional code to change the text while scrolling. This is in t_Tick( ), it checks the current scrolling speed by getting the interval of the timer, which can be adjusted by pressing + and - .
Depending on the interval, I execute the correct colorchangespeedcode.
I added one method FastScrollpeed( ) (least code) as example, for rest see source code.
Depending on the interval, the color needs to be updated each pixel up or each few pixels up (in fast case). That's why I use int i to check the pixel number and reset on end to loop the color pattern.
int i = 1;
string ScrollEnabled = "true"; void t_Tick(object sender, EventArgs e) {
if (t.Interval == 80)
{ SlowScrollSpeed(); }
else if (t.Interval == 40)
{ CenterScrollSpeed(); }
else if (t.Interval == 10)
{ FastScrollSpeed(); }
if (ScrollEnabled == "true") { scroll(richTextBox1.Handle, 1); } else { scroll(richTextBox1.Handle, 0); }
}
void FastScrollSpeed() {
if (i >= 1 && i <= 6) { richTextBox1.ForeColor = Color.OrangeRed; i = i + 1; }
else if (i >= 7 && i <= 12) { richTextBox1.ForeColor = Color.DarkOrange; i = i + 1; }
else if (i >= 13 && i <= 18) { richTextBox1.ForeColor = Color.Yellow; i = i + 1; }
else if (i >= 19 && i <= 24) { richTextBox1.ForeColor = Color.LawnGreen; i = i + 1; }
else if (i >= 25 && i <= 30) { richTextBox1.ForeColor = Color.Turquoise; i = i + 1; }
else if (i >= 31 && i <= 36) { richTextBox1.ForeColor = Color.DodgerBlue; i = i + 1; }
else if (i >= 37 && i <= 42) { richTextBox1.ForeColor = Color.RoyalBlue; i = i + 1; }
else if (i >= 43 && i <= 48) { richTextBox1.ForeColor = Color.DarkViolet; i = i + 1; }
else if (i >= 49 && i <= 53) { richTextBox1.ForeColor = Color.HotPink; i = i + 1; }
else if (i == 54) { richTextBox1.ForeColor = Color.HotPink; i = 1; }
}
void scroll(IntPtr handle, int pixels)
{
IntPtr ptrLparam = new IntPtr(0);
IntPtr ptrWparam;
SCROLLINFO si = new SCROLLINFO();
si.cbSize = (uint)Marshal.SizeOf(si);
si.fMask = (uint)ScrollInfoMask.SIF_ALL;
GetScrollInfo(handle, (int)ScrollBarDirection.SB_VERT, ref si);
if (si.nPos < (si.nMax - si.nPage))
si.nPos += pixels;
else {
ptrWparam = new IntPtr(SB_ENDSCROLL); t.Enabled = false; SendMessage(handle, WM_VSCROLL, ptrWparam, ptrLparam);
}
SetScrollInfo(handle, (int)ScrollBarDirection.SB_VERT, ref si, true);
ptrWparam = new IntPtr(SB_THUMBTRACK + 0x10000 * si.nPos);
SendMessage(handle, WM_VSCROLL, ptrWparam, ptrLparam);
if (t.Enabled == false) {
SendMessage(handle, WM_VSCROLL, (IntPtr)SB_TOP, IntPtr.Zero);
t.Enabled = true; }
}
This should be it, you should have automatic scrolling and looping text that you load from a .nfo text file, convert and view in the richTextBox, with optional color changing code.
6) Another PICTUREBOX [Disabled]
Refer to 4) The Picturebox [Clickable] But don't add any (click)Event and set the Property Enabled to False. This will do, without any code, you can drag around any disabled objects.
7) Buttons/KeyPress for Speed options [Pause, Slower, Faster] {Limited}
7.1) BUTTONS: Add some buttons you want, change the Text to P, - and + for the functions. For each Button: add the Event Click. Within these methods we put the actions to create this new functionality. I created these: buttonp (PAUSE), buttonmin (SLOWER) and buttonplus (FASTER).
Note the t.Interval, which we've set in 'Set the speed and enable Timer to send messages'
from 5) The RICHTEXTBOX. The setting that I use as default speed is t.Interval = 40;
private void buttonplus_Click(object sender, EventArgs e)
{
if (t.Interval > 10) {
t.Interval = t.Interval - 15; if (t.Interval <= 10) { buttonplus.Enabled = false; } buttonmin.Enabled = true; }
}
private void buttonmin_Click(object sender, EventArgs e)
{
if (t.Interval < 70)
{
t.Interval = t.Interval + 15;
if (t.Interval >= 70)
{ buttonmin.Enabled = false; }
buttonplus.Enabled = true;
}
}
private void buttonp_Click(object sender, EventArgs e)
{
if (t.Enabled == true) {
t.Enabled = false; }
else {
t.Enabled = true; }
}
7.2) KEYPRESS Event:
Determine where you want to have the ability to press your keyboard key. I decided my form was the best choice, but the focus just wan't there. I've used the following steps:
- I set the Form Propery
KeyPreview = True;
- I changed the
TabIndex from all the Buttons to high(er) values;
- In the Form1.Designer.cs I added
this.Focus(); to the Form, just to be sure.
Then, time for the KeyPress Events. Go to the Form Properties and select the Event options. Add KeyPress. For this one method, we can add all the keyboard keys we want.
If you want the old code with button option, check the v1.1 source release.
In v1.3 I used the following situation:
private void Form1_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == 'p') {
if (ScrollEnabled == "true")
{ ScrollEnabled = "false";}
else { ScrollEnabled = "true"; }
}
if (e.KeyChar == '=') { if (t.Interval == 40)
{ t.Interval = t.Interval - 30; }
else if (t.Interval == 80)
{ t.Interval = t.Interval - 40; }
}
if (e.KeyChar == '-') { if (t.Interval == 40) { t.Interval = t.Interval + 40; }
else if (t.Interval == 10) { t.Interval = t.Interval + 30; } }
}
8) Custom Icon (No Code)
Refer to the Form Properties of 1) The FORM [MAINFRAME]. In this section you can add an Icon for the application IN RUNNING STATE.
The .exe file itself still has it's default window Icon. To change this to the same/another Icon, open the Solution Explorer. Rightclick the name of your project (almost top in bold) and open the Properties. If the tab isn't set on Application, select that tab. You'll find the option 'Icon and manifest', where you can browse for the same .ico file. When you save this, your .exe file will also contain your selected icon.
9) 'About' Window
A new Form that opens when you click on the corresponding Question Mark PictureBox.
When you hover over the box, the Question Mark will glow. I added those 2 pictures as resource.
The next block of code shows how that Question Mark works:
void buttonQ_MouseEnter(object sender, EventArgs e)
{ this.buttonQ.BackgroundImage = ((System.Drawing.Image)(Properties.Resources.QMarkNeonGlow)); }
void buttonQ_MouseLeave(object sender, EventArgs e)
{ this.buttonQ.BackgroundImage = ((System.Drawing.Image)(Properties.Resources.QMarkNeonLessGlow)); }
private void buttonQ_Click(object sender, EventArgs e)
{
f2.TopMost = false; Form f3 = new Form3(); f3.ShowDialog(); }
By using the MouseEnter and MouseLeave Events you can change the appearance of the picture when the mouse hovers over the PictureBox. I have to disable the shield's TopMost, otherwise it will prevent users from closing the popup. When users click the richTextBox, I make sure that the TopMost of the shield (f2) is activated. It's not the best solution, but I'm satisfied with it for now. To see the complete setup, the source is your friend!
10) Music (mod format)
I wanted to have small music files (at least compared to mp3), so I've chosen the mod format[.it/.xm/.s3m/.mod]. Those can be big too, but I just download tracks < 1MB, to keep my application small. There are no simple ways to code playing music, only when you want to run .mp3/.wav using WMP. I've chosen irrKlang modplayer BASS to play my mod music files. [For more info, click the modplayer link] It was hard to find out how this would work all by myself, but I succeeded. Steps I've done for irrKlang are stated below as reference:
In the extracted irrKlang folder:
- Copy the 'Include' folder to your project folder on the system.
- Copy the correct dotNET version dll to your project folder (in my case: irrKlang-1.4.0\bin\dotnet-4\irrKlang.NET4.dll and also ikpFlac.dll and ikpMP3.dll if you want to play MP3 files.
- Copy the .exp and .lib file from this folder 'irrKlang-1.4.0\lib\Win32-visualStudio' to your project.
In your Visual Studio Project, do the following: In the Solution Explorer, rightclick 'References' and select Add Reference... Select the Browse tab, search and select your .NET dll (irrKlang.NET4.dll in my case) and add it.
Add this line to the top of your project:
using IrrKlang;
Then we can go to the actual code that loads and plays our mod music file. Refer to the first point (view a .nfo file correctly) of 5) The RICHTEXTBOX. We've used the Form1_Load( ) method there to read and convert the .nfo file and display it when the Form loads. The same thing we'll do with our music when the application starts. Paste the following line just before the Form1_Load( ) method:
IrrKlang.ISoundEngine engine = new IrrKlang.ISoundEngine();
The reason I use it before the Form loads, is because I need this variable in more methods (also to pause it)! In the Form1_Load( ) method, we add the following line:
engine.Play2D("C:\\Test\\Xaser-Aeolus.it", true);
This means we play a file on the computer, so as long as I can't include it in the project, you have to send it with the application and make sure it copies/extracts to the correct folder. Otherwise the application runs, but without music and possibly NFO file from the same folder.
Steps I've done for BASS:
I'm able to play my music from resource now, so this is easier and always works.
Download the BASS and Bass.Net dlls and add the files to the project, or copy them from my source. In Solution Explorer, go to references and add Bass.Net.dll as a reference. Unless you add them to resource, you have to put them with the final .exe as well. When the dlls are added and the reference is made, add the following line to the top:
using Un4seen.Bass;
I have a directory 'Resources' in my project and rightclick -> added my mod music file. Set properties of it: Build Action: Embedded Resource.
Using the following code in Form1_Load( ) I can play that track from resource using BASS on startup:
BassNet.Registration("xxxxxxxx@xxxxxxxx.xx", "XXXXXXXXXXXXXXX"); Bass.BASS_Init(-1, 44100, BASSInit.BASS_DEVICE_DEFAULT, IntPtr.Zero);
using (var manifestResourceStream = Assembly.GetExecutingAssembly().GetManifestResourceStream("WindowsFormsApplication1.Resources.Saga Musix - Heaven.it"))
{
if (manifestResourceStream != null)
{
int length = (int)manifestResourceStream.Length;
byte[] buffer = new byte[length];
manifestResourceStream.Read(buffer, 0, length);
int load = Bass.BASS_MusicLoad(buffer, 0, length, BASSFlag.BASS_SAMPLE_LOOP, 0);
Bass.BASS_SetConfig(BASSConfig.BASS_CONFIG_GVOL_MUSIC, vol);
Bass.BASS_ChannelPlay(load, false);
}
}
Refer to 3) The CHECKBOX [Pause Music] to see how to pause the running mod music and continue it.
11) Additional Settings
Here I place the things I've changed to let it appear nicely on other places on the computer.
Default .exe Filename: We go to the Solution Explorer and rightclick our project and then Properties. Select the 'Application' tab and change the Assembly Name to whatever you want for the exe.
As I'm in BETA, it doesn't really matter, I change it to character name to see a difference ('Angel').
If you set this, you don't have to change the name of the exe manually after you've debugged (exported) the .exe with the default 'TestApplication.exe' name.
Process Description: I noticed when running my program, that the description in Taskmanager is WindowsFormsApplication1? That's not what I want, I want something like (Argaï) NFO Viewer! To change the Process Description, go to the Solution Explorer, under YourProjectName you see the directory 'Properties'. In that directory, rightclick the AssemblyInfo.cs and click 'View Code'. [assembly: AssemblyTitle("WindowsFormsApplication1")], change the Title in what you want and it will show that title as the Description when your Process is running!
Taskbar and Taskmanager appearance: As informed before, changing the Property Text of the Form will create the 'program name' which appears when you hover over the running icon on the taskbar. The Assembly Name that is changed will present the .exe name that will be shown as process in Taskmanager.
Points of Interest
In just a few weeks I created this. The basic stuff was easy to do, but to make my richTextBox autoscroll and the way I wanted it (looped) was hard, even as changing the colors with it. But also disabling all interaction with it, without disabling the richTextBox itself was kind of hard to find out. I worked using trial and error and still do. Using some code samples from people online to achief this was really hard, as I always got errors of 'missing references' etc... I'm happy I got that all working now!
History
Changes after first upload:
Update 1.1:
General changes:
- Assembly Name changed;
- Process description changed [See 11) Additional Settings];
- Tabindex of controls changed;
- Focus added to Form (for general KeyPress option);
Functionality:
- Added 3 buttons for autoscroll speedoptions [See 7) Buttons/KeyPress];
- Added 3 KeyPress options to do the same as the buttons [See 7) Buttons/KeyPress];
I prefer the keypress, but had to test with buttons first and fix the focus etc...
Update 1.2:
Functionality:
- Added the .NFO text file as a resource to the project so people don't need to extract it to specific location anymore. I still try to add the music and dll file as a resource as well. (See the 'use a .nfo file as a resource' part of 5) The RICHTEXTBOX);
BugFixes:
- Pressing arrow keys won't allow you to enter richTextBox anymore. (See 1) The FORM);
Update 1.3:
General changes:
- Made Icon rounder (used circle shape instead of manual removing all around the circle);
- Better documented and ordened the Source Code for own reference;
Functionality:
- Changed ModPlayer 'irrKlang' to 'BASS', which supports all tracks that first didn't work and it uses lighter DLLs which make my application easier to run on more systems (See 'Steps I've done for BASS' of 10) Music (mod format);
- Removed the close button and added more KeyPresses (Escape to close application) (See move around of 1) The FORM);
- Added a fade effect when closing the application, this also fades the music with it to create a smooth closing (See Fade Effect of music and app of 1) The FORM);
- The Music is now Resource! NO need to put it all on C:\Test anymore, it runs and works everywhere (See 'Steps I've done for BASS' of 10) Music (mod format));
- Changed the default startlocation, now the application always starts in center of screen (See Properties of 1) The FORM);
- Added a questionmark button which opens a simple 'About Window'. This displays the options of the application. While this window is active, you can't interact with the application itself. If you close the application, the questionmarkbutton will be disabled while fading (See 9) 'About' Window);
- The richTextBox now has changing color functionality. It remains same speed, even if you change scrollspeed or pause the scrolling. I just added a rough pattern of strong colors, but want to make a fluent slower pattern. Will be working on that later (See Create the 2 methods t_Tick( ) and scroll( ) of 5) The RICHTEXTBOX);
- Finally I added both DLLs as resource. One can be read internally, the other one has to be written to disk. Now you can run my application anywhere without copying the DLLs with it (Refer to my source and the link about DLLs in the References at the bottom of this Article);
BugFixes:
- Added a new Form as 'Shield' which prevents interaction with the richTextBox. Now the clickbug of v1.1/1.2 is solved. It does however take the focus of the application away, so KeyPresses won't work untill you click the application again. The shield also remains on top of any other application you run, even if my app is in background! If there's another solution I'll look into that;
- Flickering application when dragging outside of the screen has been solved! (See Properties of 1) The FORM);
- 'Line Jumping Bug' fixed, text now remains on same position instead of jumping to last passed line while updating colors when users pause the scroller;
Files:
Added the first result [Top of Page];
Added the Source Code [Top of Page];
Update 1.1:
- Updated Picture in Article;
- Added v1.1 TestApplication [Top of Page];
- Added v1.1 Source Code [Top of Page];
Update 1.3:
- Updated Picture in Article;
- Added v1.3 TestApplication [Top of Page];
- Added v1.3 Source Code [Top of Page];
Bugs
- Windows 8 (always?) contains empty background of checkBox and/or Close Button.
References
Link to original code for custom Form without any Border and default Buttons:
http://www.codeproject.com/Articles/8056/Creating-Custom-Shaped-Windows-Forms-in-NET
Link to original autoscroll code which I used and changed:
http://www.codeproject.com/Articles/23363/Scrolling-a-Rich-Textbox-Automatically.
Link to my Question 'how to use .nfo as resource':
http://www.codeproject.com/Questions/519140/Usingplusaplus-NFO-plustextplusfileplusasplusresou
Link to the 'add DLL as resource' which I implemented partly:
http://www.codeproject.com/Articles/528178/Load-DLL-From-Embedded-Resource
Studying System management, using Vbscript and C# in free time to create personal projects and learning basics of CMD/Batch at current internship (Not much scripting experience, but eager to try a lot).