Microsoft Visual C++ : How to call WinMain() from a console apps main()-method / Wie man die WinMain-Methode von einer Konsolenanwendung aus aufruft

Problem

Eine C++ Anwendung hat als Konsolenanwendung den Einstiegspunkt

int main(void) {...}

aber als Win32-Anwendung den Einstiegspunkt

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)  {...}

Es wird nach einer Möglichkeit gesucht, die WinMain-Methode von einer Konsolen-Anwendung aus aufzurufen, um eine Hauptfenster in der Konsolenanwendung zu generieren.

Ansatz

MSDN definiert die WinMain()-Methode folgendermaßen:

  • hInstance ist ein Element, das als „Handle für eine Instanz“ oder „Handle für ein Modul“ bezeichnet wird. Das Betriebssystem identifiziert mithilfe dieses Werts die ausführbare Datei (EXE), wenn diese in den Arbeitsspeicher geladen wird. Das Instanzhandle wird für bestimmte Windows-Funktionen benötigt—z. B. um Symbole oder Bitmaps zu laden.
  • hPrevInstance hat keine Bedeutung. Es wurde in 16-Bit-Windows verwendet, es ist aber jetzt stets 0 (null).
  • pCmdLine enthält die Befehlszeilenargumente als Unicode-Zeichenfolge.
  • nCmdShow ist ein Flag, das angibt, ob das Hauptanwendungsfenster minimiert, maximiert oder in Normalgröße angezeigt wird.

Die WinMain()-Methode kann von der main()-Anwendung aufgerufen werden, wenn man ein hInstance Handle bekommt. Dies geht folgermaßen:

GetModuleHandle(NULL)

Lösung – Solution

// HelloWorld.cpp : Definiert den Einstiegspunkt für die Konsolenanwendung.
//

#include "stdafx.h"
#include <windows.h> 

// Das hier braucht man nur wenn man die test.wav abspielen will
//#pragma comment(lib,"winmm.lib")  //für MSV C++   

const char g_szClassName[] = "myWindowClass";

// Step 4: the Window Procedure
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch (msg)
	{
	case WM_CLOSE:
		DestroyWindow(hwnd);
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	default:
		return DefWindowProc(hwnd, msg, wParam, lParam);
	}
	return 0;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
	WNDCLASSEX wc;
	HWND hwnd;
	MSG Msg;

	//Step 1: Registering the Window Class
	wc.cbSize = sizeof(WNDCLASSEX);
	wc.style = 0;
	wc.lpfnWndProc = WndProc;
	wc.cbClsExtra = 0;
	wc.cbWndExtra = 0;
	wc.hInstance = hInstance;
	wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
	wc.hCursor = LoadCursor(NULL, IDC_ARROW);
	wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
	wc.lpszMenuName = NULL;
	wc.lpszClassName = (LPCWSTR) g_szClassName;
	wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

	if (!RegisterClassEx(&wc))
	{
		MessageBox(NULL, L"Window Registration Failed!", L"Error!",
			MB_ICONEXCLAMATION | MB_OK);
		return 0;
	}

	// Step 2: Creating the Window
	hwnd = CreateWindowEx(
		WS_EX_CLIENTEDGE,
		(LPCWSTR) g_szClassName,
		L"Eine Mischung aus Console und Window App",
		WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT, CW_USEDEFAULT, 240, 120,
		NULL, NULL, hInstance, NULL);

	if (hwnd == NULL)
	{
		MessageBox(NULL, L"Window Creation Failed!", L"Error!",
			MB_ICONEXCLAMATION | MB_OK);
		return 0;
	}

	ShowWindow(hwnd, nCmdShow);
	UpdateWindow(hwnd);

	// Step 3: The Message Loop
	while (GetMessage(&Msg, NULL, 0, 0) > 0)
	{
		TranslateMessage(&Msg);
		DispatchMessage(&Msg);
	}
	return Msg.wParam;
}


int main()
{
	// Das hier spielt eine Datei test.wav im gleichen Verzeichnis
	//PlaySound(L"test.wav", NULL, SND_ASYNC);
	
	WinMain(GetModuleHandle(NULL), 0, 0, 1);

	printf("Se hams Fenster geschlossen!");
	getchar();

	return 0;
}
Veröffentlicht unter C++, Programmierung | Hinterlasse einen Kommentar

Bilder vom zugefrorenem Aueweiher

Veröffentlicht unter Allgemein | Hinterlasse einen Kommentar

Cubase 9 Pro: Kontakt Player 5 (Sennheiser DrumMic’a) not available under VST Instruments / Kontakt Player 5 (DrumMic’a) nicht gelistet bei VST Instrumente

Problem

Nach der Installation von Sennheisers Drummica (bzw. Kontakt 5 Player) wird unter Cubase 9 Pro der Kontakt Player 5 nicht als Auswahl angezeigt. Diesen muss man auswählen, um Kontakt 5 Player Instrumente (z.B. Drummica) zu nutzen.

After the installation of Sennheisers DrumMic’a (specifically Kontakt Player 5) the Kontakt Player is not listed in the VST Instruments section.

Analysis – Analyse

Die Kontakt 5 Player Installation hat ein 64 Bit Verzeichnis mit den DLL’s angelegt. Die DLL’s wurden weder in VST Verzeichnisse kopiert noch wurde der neue Kontakt 5 Player Pfad als VST Verzeichnis definiert.

„C:\Program Files\Native Instruments\VSTPlugins 64 bit“

After the Kontakt 5 Player installation a new 64 Bit directory is created with the DLL files, that is currentyl not in the VST Plugin paths.

„C:\Program Files\Native Instruments\VSTPlugins 64 bit“

Ansatz – Approach

Anstelle die DLL’s in ein VST-Verzeichnis zu kopieren, legen wir den Pfad als neuen VST-Plugin-Pfad an.

Instead of copying the DLL files in a VST directory, we will create this folder as new VST plugin path.

Lösung – Solution

Unter „Geräte->Plug In Manager“ fügen wir die Kontakt 5 Player DLL’s hinzu, indem wir den Pfad „C:\Program Files\Native Instruments\VSTPlugins 64 bit“ anlegen. Nun wird Kontakt 5 Player gefunden.

Anmerkung: Sollte es Probleme beim Upgrade auf die neue Kontakt 5 Player Version geben (Download fehlgeschlagen im Service Center), kann man die neuste Version einfach von der Native Instruments Website runterladen und neu installieren. DrumMic’a Libraries sind danach in der neuen Kontakt 5 Player Version auswählbar.

Under „Devices->Plug In Manager“ we add the Kontakt 5 Player DLL path as new VST directory „C:\Program Files\Native Instruments\VSTPlugins 64 bit“. After that Kontakt 5 Player will be found.

Veröffentlicht unter Aufnahmetechnik, Musik, Musikproduktion | Hinterlasse einen Kommentar

Finde den versteckten Goldschatz

Hallo lieber Besucher!

In einzelnen Artikeln dieses Blogs befinden sich Hinweise zu einem verborgenem Piratenschatz aus dem 17. Jahrhundert.

Du wirst in den Artikeln diverse Indizien finden, die sich zu einer schlüssigem Schatzkarte zusammensetzen.

Wir haben Dir dieses Rätsel nicht besonders leicht gemacht, daher sind bereits viele Deiner Vorgänger gescheitert.

Dies ist kein Gewinnspiel, sondern eine echte Schatzsuche!

Ich wünsche Dir viel Erfolg beim Suchen.

Viele Grüße
Björn Karpenstein

Veröffentlicht unter Allgemein | Hinterlasse einen Kommentar

IBM Doors DXL: Be resistent against hard coded module paths and names with uniqueID and itemFromID / Vorbeugung von DXL Fehlern durch Verschiebung von Modulen anhand der uniqueID

Problem

In the source code, you can find modulenames with full qualified path+name, what leads to DXL errors in case of a module movement.
Im DXL Code werden Module oft mit ihrem vollem Pfad und Namen hart codiert. Wird das Modul später verschoben, kommt es zu DXL Fehlern.

Ansatz – Approach

– Find out the uniqueID of the Module (here a fictive ALM and UIT Module) / Ermitteln Sie die uniqueID des Moduls
– get the full qualified name of the module / Vollständigen Modulnamen mit Pfad mit itemFromID ( uniqueID ) ermitteln
– open module / Modul laden

Solution – Lösung

Ermittlung der unique ID eines Moduls:

  • Öffnen des Moduls / Open module
  • Öffnen des DXL Fensters / Open DXL window (Menu — Tools — Edit DXL)
Module m = current;
print uniqueID(m) "";

Loading of the module / Laden des Modules

// UIT Module ID: 00005771
// ALM Module ID: 0000576e
string moduleID="00005771"; // Es soll das UIT Module geladen werden
string modulePath = fullName itemFromID(moduleID) "";
Module selectedModule=read(modulePath, true, true);
Veröffentlicht unter DXL, IBM DOORS | Hinterlasse einen Kommentar

Impressionen vom zugefrorenem Haunestausee im Winter

Bilder vom Haunesee vom 21. Januar 2017

Veröffentlicht unter Allgemein | 2 Kommentare

C#.NET: ZIP Dateien entpacken und im Zielverzeichnis ggf. überschreiben / Uncomrpess ZIP to a folder and overwrite existing

Problem

Die ZipFile.ExtractToDirectory(zip,target)-Methode in C# überschreibt keine vorhandenen Dateien, sondern schmeisst eine Exception.
The ZipFile.ExtractToDirectory(zip,target)-method in c# is not overwriting existing files, but throws an exception

Vorraussetzung – Prerequirements

.NET Framework der Version 4.5
Referenzen/References:
System.IO.Compression.dll
System.IO.Compression.FileSystem.dll

You have to import the using

using System.IO.Compression;

Ansatz – Approach

Durch die Iteration über das ZIP-Archiv lassen sich die einzelnen Dateien entpacken, wobei die Methode System.IO.Compression.ZipArchiveEntry.ExtractToFile(string path, bool overwrite) ein Überschreiben erlaubt.

The iteration on System.IO.Compression.ZipArchive with System.IO.Compression.ZipArchiveEntry.ExtractToFile(string path, bool overwrite) allows to overwrite existing files.

Lösung – Solution

public void ZipFileExtractToDirectory(string zipPath, string extractPath)
{
  using(System.IO.Compression.ZipArchive archive = ZipFile.OpenRead(zipPath))
  {
    foreach(ZipArchiveEntry entry in archive.Entries)
    {
      string completeFileName = Path.Combine(extractPath, entry.FullName);
      string directory = Path.GetDirectoryName(completeFileName);

      if (!Directory.Exists(directory))
      {
        Directory.CreateDirectory(directory);
      }
      entry.ExtractToFile(completeFileName, true);
    }
  }
}
Veröffentlicht unter C#, Programmierung | Hinterlasse einen Kommentar

ASP.NET asp:GridView gruppieren von identischen Spalten oder nach einer bestimmten Spalte / grouping identical GridView Rows/Cells or by column

Problem

Ein vorsortiertes asp:GridView (Screenshot: Original) soll nach einer Spalte (Screenshot Algorithmus 1) oder nach identischem Inhalt (Screenshot Algorithmus 2) sortiert werden.

Prämisse / Vorraussetzungen

  • Das GridView sollte vorher (z.B. mit ORDER BY-Klausel) vorsortiert werden um die bestmöglichen Ergebnisse zu erzielen.
  • Wenn nach einer Spalte gruppiert wird, sollte diese Spalte erstrangig (also erste Erwähnung in ORDER BY-Klausel) stattfinden.

Ansatz – Approach

  • Erschaffung eines Algorithmus, welcher über die RowSpan-Eigenschaft Zellen miteinander verbindet.
  • Vergleich ob der Text der Vorgängerspalte der gleiche ist
    • JA:
      • Unsichtbarschalten der aktuellen Zeilen
      • inkrement des RowSpan-Wertes der Vorgängerzeile
      • Vorgängerzeile ist nun die einzig Sichtbare
    • Nein: Weitermachen

Lösung – Solution

Vorgehensweise

1.) Auf das GridView klicken
2.) Im Objekt-Inspektor auf „Events/Ereignisse“ (also der Blitz) klicken
3.) Doppelklick auf das Ereignis „OnDataBound“
4.) in die erzeugte Methode kann der folgende Code kopiert werden

Algorithmus 1: GridView-Gruppierung nach einer Spalte

/****************************************
 * ASP:GridView Grouping Algorithmus
 * Quelle http://www.capri-soft.de/blog
 ****************************************/
// Nach dieser Spalte soll gruppiert werden
int k = 1;

// Für alle Zeilen (VON UNTEN NACH OBEN)
for (int i = GridView1.Rows.Count - 1; i > 0; i--)
{
	GridViewRow row = GridView1.Rows[i];
	GridViewRow previousRow = GridView1.Rows[i - 1];
	// Für alle Spalten
	for (int j = 0; j < row.Cells.Count; j++)
	{
		if ((row.Cells[k].Text == previousRow.Cells[k].Text) 
                    && (row.Cells[j].Text == previousRow.Cells[j].Text))
		{
			if (previousRow.Cells[j].RowSpan == 0)
			{
				if (row.Cells[j].RowSpan == 0)
				{
					previousRow.Cells[j].RowSpan += 2;
				}
				else
				{
					previousRow.Cells[j].RowSpan = 
                                        row.Cells[j].RowSpan + 1;
				}
				row.Cells[j].Visible = false;
			}
		}
	}
}

Algorithmus 2: GridView-Gruppierung für alle identischen Zellen einer GridView-Spalte

/****************************************
 * asp:GridView Grouping Algorithmus
 * Quelle: http://www.capri-soft.de/blog
 ****************************************/
// Für alle Zeilen (VON UNTEN NACH OBEN)
for (int i = GridView1.Rows.Count - 1; i > 0; i--)
{
	GridViewRow row = GridView1.Rows[i];
	GridViewRow previousRow = GridView1.Rows[i - 1];
	// Für alle Spalten
	for (int j = 0; j < row.Cells.Count; j++)
	{
		if (row.Cells[j].Text == previousRow.Cells[j].Text)
		{
			if (previousRow.Cells[j].RowSpan == 0)
			{
				if (row.Cells[j].RowSpan == 0)
				{
					previousRow.Cells[j].RowSpan += 2;
				}
				else
				{
					previousRow.Cells[j].RowSpan = 
                                        row.Cells[j].RowSpan + 1;
				}
				row.Cells[j].Visible = false;
			}
		}
	}
}
Veröffentlicht unter .NET, C# | Hinterlasse einen Kommentar

ASP.NET: Generate Pie Charts over GET params from URL / Tortendiagramme über URL Get Request generieren

Problem

Es sollen Tortendiagramme in ASP.NET angezeigt werden.

Ansatz

Runterladen von

Die Diagramme können über einen Request-Parameter erstellt werden:

http://localhost:51241/PieChartGetParams.aspx?headline=Ich mag Bier&pieces=ein;20;komisches;50;Tortendiagramm;40

  • Headline: Ist die Überschrift des Tortendiagramms
  • Pieces: Abwechselnd durch Semikolon getrennt immer Tortenstück1;Wert1;Tortenstück2;Wert2;…;TortenstückN;WertN

Lösung – Solution

Laden Sie HighCharts runter und passen Sie untenstehenden Quellcode an:

<script src="pfad/zu/highcharts.js"></script>
<script src="charts/zu/exporting.js"></script>
<script type="text/javascript" src="Pfad/zu/jquery-1.4.1.min.js"></script>

Erstellen Sie eine ASP.NET-Seite mit folgendem Inhalt:

&lt;%@ Page Language="C#" AutoEventWireup="true" CodeFile="PieChartGetParams.aspx.cs" Inherits="PieChart" %&gt;
 
 <script type="text/javascript" src="Scripts/jquery-1.4.1.min.js"></script><script src="charts/highcharts.js"></script><script type="text/javascript">
  $(function () {
    function drawPieChart(seriesData) {
       $('#container').highcharts({
	 chart: {
	   plotBackgroundColor: null,
           plotBorderWidth: null,
           plotShadow: false,
           type: 'pie'
	 },
	title: {
          text: '<%=Request.Params["headline"] %>'
	},
	tooltip: {
          pointFormat: '{series.name}: <b>{point.percentage:.1f}%</b>'
        },
        plotOptions: {
           pie: {
            allowPointSelect: true,
            cursor: 'pointer',
            dataLabels: {
              enabled: true,
              format: '<b>{point.name}</b>: {point.y} ',
              style: {
               color: (Highcharts.theme && Highcharts.theme.contrastTextColor) || 'black'
              }
           }
        }
     },
     series: [{
       name: "Percentage",
       colorByPoint: true,
       data: seriesData
     }]
  });
 }

 function addToPieChart(arr, key, value)
 {
    var obj = {};
    obj.name = key;
    obj.y = value;
    arr.push(obj);
 }

 var arr = []

 <% if (Request.Params["pieces"] != null) { string piecesParam = Request.Params["pieces"]; char[] splitchar = { ';'}; int i = 0; string label = ""; foreach(string s in piecesParam.Split(splitchar)) { if(i%2==0) { label = s; } else { Response.Write("addToPieChart(arr, '" + label + "', " + s + ");"); } i++; } } %>

  var myJsonString = JSON.stringify(arr);
  var jsonArray = JSON.parse(JSON.stringify(arr));

  drawPieChart(jsonArray);
});
</script>
    
    <script src="charts/modules/exporting.js"></script>
 

 

 

 

 

Veröffentlicht unter .NET, C#, Microsoft IIS Server | Hinterlasse einen Kommentar

Excel und VBA: Durchlaufen aller Worksheets/Tabellen in einem Workbook/einer Arbeitsmappe und exportieren in Textdatei

Problem

Es sollen alle Tabellen einer Excelmappe durchlaufen und in eine Textdatei geschrieben werden

Lösung

Sub Schaltfläche1_Klicken()
    ' Erzeugt eine Textdatei
    On Error Resume Next
    
    Dim i, j As Integer
    Dim letzteZeile As Integer
    Dim workbookName As String
    Dim artikelname As String
    Dim EANNummer As String
    Dim UmsatzVKBrutto As String
    Dim Absatz As String
    Dim VKPreisSap As String
    Dim UST As String
    
    Dim csvZeile As String
    
    Open "d:\daten\liste.txt" For Output As #1
    
    For i = 2 To ThisWorkbook.Sheets.Count - 1
        workbookName = ThisWorkbook.Sheets(i).Name
        ' Finde die letzte Zeile
        letzteZeile = Worksheets(workbookName).Cells.Find("*", [A1], , , xlByRows, xlPrevious).Row + 1
        
        For j = 1 To letzteZeile
            If Trim(ThisWorkbook.Sheets(i).Cells(j, 1)) <> "" Then
                artikelname = ThisWorkbook.Sheets(i).Cells(j, 1)
                EANNummer = ThisWorkbook.Sheets(i).Cells(j, 2)
                UmsatzVKBrutto = ThisWorkbook.Sheets(i).Cells(j, 3)
                Absatz = ThisWorkbook.Sheets(i).Cells(j, 4)
                
                If IsError(ThisWorkbook.Sheets(i).Cells(j, 5).Value) = True Then
                    VKPreisSap = "#nv"
                Else
                    VKPreisSap = CStr(ThisWorkbook.Sheets(i).Cells(j, 5))
                End If
                
                If IsError(ThisWorkbook.Sheets(i).Cells(j, 6).Value) = True Then
                    UST = "#nv"
                Else
                    UST = CStr(ThisWorkbook.Sheets(i).Cells(j, 6))
                End If
                
                csvZeile = workbookName & ";" & artikelname & ";" & EANNummer & _
                ";" & UmsatzVKBrutto & ";" & Absatz & ";" & VKPreisSap & ";" & UST
                Print #1, csvZeile
                
            End If
        Next j
    Next i
    
    Close #1

End Sub
Veröffentlicht unter VBA | Hinterlasse einen Kommentar