Tanpohp

Tag: Visual Studio

HowTo: Embedded Resource aus XAML und C# nutzen

by on Apr.18, 2010, under HowTo, MicroMite

Bilder und weiteren Inhalt in eine EXE einzubinden und zu nutzen hat einen besonderen Reiz: man muss keine Fehlerbehandlung einbauen die zur Laufzeit nicht auffindbare Dateien behandeln, niemand (oder zumindest die meisten) können diese Inhalte werde auslesen noch verändern.

Damit die Ressource eingebettet werden kann, muss diese in Visual Studio erst einmal zum Projekt hinzugefügt werden. An einem Beispiel gehe ich das mal durch:Embedded PNG-File Wie im Bild rechts zu sehen ist, habe ich ein Bild Delete.png zum Projekt hinzugefügt. Um dieses aus XAML anzusprechen bedarf es einer speziellen Einstellung: Im Eigenschaftenfenster muss unter “Build Action” Resource ausgewählt sein. Die allgemeine Syntax würde lauten:

   Icon="/{AssemblyName};component/directory/Image.ico"

Wobei {AssemblyName} durch den Namen des Assembly ersetzt werden muss (meist der Name des WPF-Projektes). Der anschließenden Teil (“;component/”) muss ebenfalls vorhanden sein und ist immer gleich. Den AssemblyName kann auch zur Laufzeit mit folgendem Befehl abgefragt werden:

   this.getType().Assembly.GetName().Name;

Und das ganze am Beispiel des Icons eines Window:

<Window 
   x:Class="MicroMite.Gui.MainWindow"
   Title="MicroMite" Height="400" Width="280"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   Icon="/MicroMite;component/content/icon/miscellaneous/MiteWindowIcon.ico"/>

Um aus C# mittels Programmcode auf die Ressource zugreifen zu können, muss diese in den Eigenschaften als “Embedded Ressource” unter “Build Action” aufgeführt werden. Mir ist es bisher nicht gelungen eine “Resource” aus C# anzusprechen oder eine “Embedded Ressource” unter XAML – sehr schade eigentlich. Ansonsten geht das wie folgt:

   String uri = @"content.icon.miscellaneous.Delete.png";
   Assembly assembly = this.getType().Assembly;
   String assemblyName = ssembly.GetName().Name;
   System.IO.Stream stream = assembly.GetManifestResourceStream(assemblyName+"." + uri);
   Icon.Resource = new PngBitmapDecoder(stream,
                                         BitmapCreateOptions.PreservePixelFormat,
                                         BitmapCacheOption.Default).Frames[0];

Da die Inhalte roh in die Exe eingebettet werden, behalten diese ihr Format bei und müssen erst mit einem passenden Decoder zu einer ImageSource konvertiert werden. Im Namespace  System.Windows.Media.Imaging stehe passenden Decoder für die Bildformate PNG, JPEG, BMP, GIF, TIFF und WMB  bereit. Ich werde demnächst eine DLL hier einstellen, welche all diese Funktionalitäten abstrahiert.

1 Comment :, , , more...

HowTo – Trayicon mit Contextmenu

by on Apr.18, 2010, under HowTo, MicroMite

Im folgenden geht es um die Erstellung eines Trayicons (oder auch Notifyicon) mit einem ContextmenuTray from Windows. Trayicons sind die kleinen Symbole die links neben der Uhr im Windows angezeigt werden und meist von Instantmessangern und Antivirenprogrammen besetzt werden. Bei mir sieht das in etwa so wie auf nebenstehendem Bild aus.

WPF selbst bietet keine Trayicon-Komponente. Aber im Namespace System.Windows.Forms gibt es eine Klasse NotifyIcon die diesen Zweck erfüllt. Bei einem WPF-Projekt muss jetzt als erstes die passenden Referenz hinzugefügt werden:

  • Klick auf Referenzen -> Referenz hinzufügen
  • Suche nach System.Windows.Forms
  • Ok

Im Anschluss eine Membervariable vom Typ NotifiyIcon erstellen welche im Konstruktor initialisiert wird:

private System.Windows.Forms.NotifyIcon trayicon;
public Window1(){
   trayicon = new System.Windows.Forms.NotifyIcon();
   trayicon.BalloonTipTitle = "BalloonTitle";
   trayicon.BalloonTipText = "BalloonText";
   trayicon.Icon = new System.Drawing.Icon(@"C:\icon.ico");
   trayicon.Text = "Text on hover icon"
   trayicon.MouseClick += new System.Windows.Forms.MouseEventHandler(trayiconClickHandler);
   trayicon.Visible = true;
}

Die meisten Eigenschaften dürften selbsterklärend sein. Falls nicht ist hier die entsprechende Referenz von Microsoft. Der BallonTip ist eine kleine Sprechblase mit Informationen anzeigt. Diese wird mittels ShowBalloonTip(3000) für 3 Sekunden lang angezeigt wird. Ganz wichtig ist die Eigenschaft Visible auf true zu setzen, da diese normalerweise deaktiviert ist. Das NotifyIcon besitzt auch eine Click-Event welches anstelle des MouseClick-Events verwendet werden könnte. Diese bietet allerdings nicht die Möglichkeit zu unterscheiden welche Maustaste gedrückt wurde.

Die Eigenschaft NotifiyIcon.ContextMenu ist vom Typ ein Array aus MenuItems. Bereits bestehende könnten hier folglich wiederverwendet werden:


   System.Windows.Forms.MenuItem[] menuitems= new System.Windows.Forms.MenuItem[2];
   menuitems[0] = new System.Windows.Forms.MenuItem("Go to Google", gotoClickHandler);
   menuitems[1] = new System.Windows.Forms.MenuItem("Exit", exitClickHandler);

Ein MenuItem erwartet eine Beschriftung sowie ein EventHandler welcher beim Klicken aufgerufen wird. Kleine Anmerkung: MenuItem hat eine Eigenschaft MenuItems, es ist also folglich möglich verschachtelte Menüs zu erzeugen. Im folgenden nun die Eventhandler, der das Hauptfenster bei Linksklick öffnet bzw. versteckt:

void trayiconClickHandler(object sender, System.Windows.Forms.MouseEventArgs e)
{
   if (e.Button == System.Windows.Forms.MouseButtons.Left)//right is for context menu
   {
      if (IsVisible) Hide();
      else this.Show();
   }
}

Der erste Eventhandler im Kontextmenu zeigt wie eine beliebige URL im Standardbrwoser aufgerufen werden kann. Der zweite beendet lediglich das Programm:

private void goToMiteClickHandler(object sender, System.EventArgs e)
{
   System.Diagnostics.Process.Start("www.google.de");
}
private void exitClickHandler(object sender, System.EventArgs e)
{
   Close();
}

Alles im Allem also gar nicht so schwer, man muss nur wissen wie.

Comments Off on HowTo – Trayicon mit Contextmenu :, , , , , more...

HowTo – DLL erstellen und benutzen unter Visual Studio 2008

by on Jun.19, 2009, under HowTo

Für unsere Bachelorarbeit erstellen wir ein Programm zur Verzerrungsfreien Darstellung von Panoramen auf gekrümmten Flächen. Uns erschien es sinnvoll, den Verzerrungsalgorithmus in eine DLL auszugliedern, damit er dann ggf. auch von Anderen verwendet werden kann. Allerdings hatten wir keinen blassen Schimmer, wie man eine eigene DLL erstellt und anzapft. Auf der Suche nach Informationen fanden wir bei codeguru.com eine Anleitung. Obgleich diese sehr hilfreich war, brauchten wir recht lange um das Beispiel in VS2008 umzusetzen. Des weiteren enthält die Anleitung auf codeguru.com einen kleinen Fehler der hier bereits korrigiert ist.

Deshalb kommt hier jetzt eine Schritt-für-Schritt Anleitung:

Create a DLL

  • VS => File => New Projekt => Visual C++ => Win32 => Win32 Console Application
    • Name: DLLPROJECT
    • Application type: dll
    • Additionnal Option: empty project
  • Add => Header File to “Header files” named DLLPROJECT.h
    • add following code:
    • #ifndef _DLL_TEST
      #define _DLL_TEST
      #include <iostream>

      #if defined DLL_EXPORT
      #define DECLDIR __declspec(dllexport)
      #else
      #define DECLDIR __declspec(dllimport)
      #endif

      extern “C” {
      DECLDIR void teststd(void);
      }
      #endif

  • Add => C++ file to “Source files” named DLLPROJECT.cpp
    • add following code:
    • #include <iostream>
      #define DLL_EXPORT

      #include “DLLPROJECT.h”

      extern “C”
      {
      DECLDIR void teststd(void)
      {
      std::cout << “Hallo World – FROM DLLPROJECT” << std::endl;
      }
      }

Usage of the DLLPROJECT.dll in a C++ Projekt

  • VS => File => New Projekt => Visual C++ => Win32 => Win32 Console Application
    • same solution
    • Name: APPLICATIONPROJECTCPP
    • Application type: console application
    • Additionnal Option: empty project
  • Add => C++ file to “Source Files” named APPLICATIONPROJECTCPP.cpp
    • add following code:
    • #include <iostream>
      #include <DLLPROJECT.h>
      #pragma comment (lib, "DLLPROJECT.lib")
      int main(){
      teststd();
      float f;
      std::cin >> f;
      }

  • Build => Project only => Build only DLL-Project
  • APPLICATIONPROJECTCPP => Properties => C/C++ => General => Additional Include Directories
    • add path to Headerfile of DLLPROJECT ($(SolutionDir)\DLL-Project\)
  • APPLICATIONPROJECTCPP => Properties => C/C++ => Linker => Additional Library Directories
    • add path to *.lib-File of DLLPROJECT ($(TargetDir)\)
  • APPLICATIONPROJECTCPP => Set as StartUp Project

Usage of the DLLPROJECT.dll in a C# Projekt

  • VS => File => New Projekt => Visual C# => Windows => Console Application
    • same solution
    • Name: APPLICATIONPROJECTCS
    • Application type: console application
    • replace code with following:
    • using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Text;
      using System.Runtime.InteropServices;

      namespace CSharpTest
      {
      class Program
      {
      [DllImport(“DLLPROJECT.dll”)]
      private static extern void teststd();

      static void Main(string[] args)
      {
      teststd();
      Console.Read();
      }
      }
      }

  • Build => Configuration Manager => Plattform => New …
    • x86
  • APPLICATIONPROJECTCS => Set as StartUp Project
  • copy of DLLPROJECT.dll nach APPLICATIONPROJECTCS/bin/x86/debug
  • Debug
Comments Off on HowTo – DLL erstellen und benutzen unter Visual Studio 2008 :, , , more...

Looking for something?

Use the form below to search the site:

Still not finding what you're looking for? Drop a comment on a post or contact us so we can take care of it!

Visit our friends!

A few highly recommended friends...