Deutsches Lilypond Forum (Archiv)

Allgemein => Allgemeine Diskussion => Thema gestartet von: ding-dong am Dienstag, 1. April 2008, 11:26

Titel: point & click
Beitrag von: ding-dong am Dienstag, 1. April 2008, 11:26
wenn ich im von lilypond generierten pdf-file mit der maus über noten fahre, erscheint ein fenster mit dem text textedit://C:/pfad und filename:14:6:6wenn ich dann aber darauf klicke, geschieht nur, dass ein message-fenster kurz auftaucht und wieder verschwindet.
dabei sollte das file mit dem lilypond-code an der richtigen zeile und position angezeigt werden.
wer weiss rat?
Titel: Re: point & click
Beitrag von: etilli33 am Dienstag, 1. April 2008, 16:16
Da weiß ich leider auch keinen direkten Rat. Eine Anleitung findet sich hier:

http://kainhofer.com/~lilypond/Documentation/user/lilypond-program/Point-and-click.de.html#Point-and-click

die ist aber hauptsächlich für UNIX zugeschnitten, weiß nicht, wie sich das auf Windows übertragen lässt. Eine Alternative ist Jedit, ein Texteditor mit einem zusätzlichen LilypondTool, das, so weit ich mich erinnere, einen eigenes PDF-Programm mit sich bringt, welches auch point-and-klick unterstützt. Geh zum vorigen Link  und im Menü einen Punkt aufwärts zu "Texteditoren".

Hoffe, das hat geholfen.

Till
Titel: Re: point & click
Beitrag von: ding-dong am Dienstag, 1. April 2008, 17:41
danke für den tip, hilft leider auch nicht viel, da ich meinen gewohnten editor weiterverwenden möchte und zudem jEdit- zumindest als ich es ausprobierte - keine unterstützung mit includierten files fertigbrachte ("deutsch.ly")
Titel: Re: point & click
Beitrag von: stargazer am Samstag, 19. April 2008, 12:55
... ich möchte auch nicht auf meinen gewohnten Editor verzichten. Trotzdem ist der Link-Hinweis in Acrobat recht hilfreich, zumindest die Zeile zu finden.

Ich rätsle jedoch, was die beiden zusätzlich Parameter bedeuten könnten, bzw. wie man sie manuell auswerten könnte.

Was versteckt sich z.B bei "8:5:12" hinter der "5" und der "12"?

schöne Grüße
Dieter
Titel: Re: point & click
Beitrag von: ding-dong am Samstag, 19. April 2008, 13:44
eine kleine hilfe ist das sicher!

zeile/position/länge ??
Titel: Re: point & click
Beitrag von: stargazer am Samstag, 19. April 2008, 15:12
Zeile ist schon mal gut  ;D

Die beiden anderen Werte nehmen jedenfalls mit ihrer X-Position im Ly-File zu.

Position will aber auch nicht ganz passen. Zwei Stimmen, gleicher Takt, gleiche Notenlängen, trotzdem können die Werte in den beiden Stimmen abweichen.

Auch die "Länge" passt nicht ganz.

Momentan schreibe ich jeden Takt in eine Zeile, um Abweichungen im Notenbild schneller zu finden.
Ich würde lieber Zeile für Zeile schreiben, aber dazu müsste man die in Adobe angezeigten Parameter besser verstehen.

schöne Grüße
Dieter
Titel: Re: point & click
Beitrag von: etilli33 am Samstag, 19. April 2008, 19:26
Der zweite Wert ist die Spalte in deinem Textfile -- wenn du einen guten Texteditor hast, zeigt er dir das an. Also in anderen Worten das wievielte Zeichen in der Zeile.

Die dritte Zahl weiß ich auch nicht, was sie bedeutet, bei mir ist sie mit der zweiten identisch.

Gruß
Till
Titel: Re: point & click
Beitrag von: martinusbaum am Samstag, 19. April 2008, 20:25
noch ein Hinweis:
jedit  unterstützt deutsch.ly schon......
wichtig ist, beim Speichern das richtige Dateiformat für windows mit erweitertem Zeichensatz einzustellen: Options - General - UTF 8
Dann klappts
Titel: Re: point & click
Beitrag von: stargazer am Sonntag, 20. April 2008, 18:24
Der zweite Wert ist die Spalte in deinem Textfile ....
Stimmt - allerdings muss man das Blank vor dem Notenwert bei der Zählung berücksichtigen.

--> Adobespalte +1 = Spalte im Editor (vorausgesetzt der Editor zählt die TABs korrekt)

schöne Grüße
Dieter
Titel: Re: point & click
Beitrag von: Andre am Donnerstag, 24. April 2008, 19:29
Die Anleitungen die es gibt sind alle nur für Linux.

Die Zahlen bedeuten: LINE:CHAR:COLUMN
So steht es in der Datei Lilypond\usr\bin\lilypond-invoke-editor. Diese Datei soll auch peer Anleitung gestartet werden. Sie ist aber in Guile geschrieben, welches Windows nicht versteht.

Das mit der Verlinkung bei Windows funktioniert auch anders, nämlich mit der registry.

Meine Lösung ist nicht sehr Elegant und Ausgereift aber villeicht könnt ihr sie noch verfeinern.

Als erstes muss Windows das Protokoll Textedit: beigebracht werden.

Code: (Lily.reg) [Auswählen]
REGEDIT4

[HKEY_CLASSES_ROOT\textedit]
@="URL:textedit Protocol"
"URL Protocol"=""

[HKEY_CLASSES_ROOT\textedit\shell]

[HKEY_CLASSES_ROOT\textedit\shell\open]

[HKEY_CLASSES_ROOT\textedit\shell\open\command]
@="\"C:\\Batch\\Lily.bat\" \"%1\""
Jetzt reagiert Windows bei allen Links die mit textedit:// anfangen und startet Lily.bat dem mit %1 der Link übergeben wird.

Nun muss man den Link auseinanderpfriemeln:
Code: (Lily.bat) [Auswählen]
@echo off
FOR /F "tokens=3,4,5 delims=:" %%G IN ("%1") DO @set EXT=+%%H C:%%G
set EXT=%EXT:/=\%
"C:\Program Files\Vim\vim71\gvim" %EXT%
In meinem Fall wird nun gvim mit der entsprechenden Zeile gestartet.
Allerdings wird bei mir im Firefox immer ein leerer Tab geöffnet und ein Dosfenster.
Titel: Re: point & click
Beitrag von: stargazer am Donnerstag, 24. April 2008, 21:04
In meinem Fall wird nun gvim mit der entsprechenden Zeile gestartet.
Ist dies die max. Funktion ....... nur in der Zeile gestartet?

Richtig nützlich ware es nur, wenn der Cursor auch in der entsprechenden Spalte stünde.

Bei mir ist in solchen Situationen die LY-Datei bereits offen, da ich ja editiere. Funktioniert die ganze Geschichte auch, wenn die Datei bereits geöffnet ist?
Ein üblicher Editor reagiert beim wiederholten Öffnen mit Meldungen, die man wegklicken muss.

In Adobe mit dem Mauspfeil auf die Note gehen, Zeile und Spalte merken, in den Editor wechseln und Zeile und Spalte suchen ...
Es gehört einiges dazu, dies zu toppen.

Gruß
Dieter

Titel: Re: point & click
Beitrag von: ding-dong am Donnerstag, 24. April 2008, 23:49
leider kenne ich mich mit der registry nicht so aus - kannst du etwas näher erläutern, was unter den einzelnen items gemacht wird.
zb.

Zitat
[HKEY_CLASSES_ROOT\textedit]
@="URL:textedit Protocol"
"URL Protocol"=""

was bedeutet dieses @ und wie muss ich dies im registry definieren? ist das ein neuer schlüssel?


danke
ding-dong
Titel: Re: point & click
Beitrag von: Andre am Freitag, 25. April 2008, 08:14
In meinem Fall wird nun gvim mit der entsprechenden Zeile gestartet.
Ist dies die max. Funktion ....... nur in der Zeile gestartet?

Richtig nützlich ware es nur, wenn der Cursor auch in der entsprechenden Spalte stünde.

Bei mir ist in solchen Situationen die LY-Datei bereits offen, da ich ja editiere. Funktioniert die ganze Geschichte auch, wenn die Datei bereits geöffnet ist?
Ein üblicher Editor reagiert beim wiederholten Öffnen mit Meldungen, die man wegklicken muss.

In Adobe mit dem Mauspfeil auf die Note gehen, Zeile und Spalte merken, in den Editor wechseln und Zeile und Spalte suchen ...
Es gehört einiges dazu, dies zu toppen.

Gruß
Dieter


Das liegt natürlich jetzt am Editor. Das "normale" gvim (windows) kann nicht in die spalte springen. Das scheint aber in der linuxversion zu funktionieren.
Ja man muss so den gvim immer nach dem Editieren schliessen. In der Anleitung steht aber auch das man den Vim als Server startet (--remote). Wie das unter Windows geht habe ich keine Ahnung.

Wer die Lily.bat ändern will:

"C:\Program Files\Vim\vim71\gvim" %EXT%^-- Da muss der Pfad zu euren Editor rein.

FOR /F "tokens=3,4,5 delims=:" %%G IN ("%1") DO @set EXT=+%%H C:%%G^-- %%G ist der Pfad zur Datei ohne Laufwerksbuchstabe. Das Laufwerk wird dann als C: eingefügt. Wer seine Dateien woanders hat muss halt den Buchstaben entsprechend ändern.
%%H ist die Zeile
Man kann jetzt noch %%I hinzufügen und hat dann die Spalte.
Titel: Re: point & click
Beitrag von: Andre am Freitag, 25. April 2008, 08:34
leider kenne ich mich mit der registry nicht so aus - kannst du etwas näher erläutern, was unter den einzelnen items gemacht wird.
zb.

Zitat
[HKEY_CLASSES_ROOT\textedit]
@="URL:textedit Protocol"
"URL Protocol"=""

was bedeutet dieses @ und wie muss ich dies im registry definieren? ist das ein neuer schlüssel?


danke
ding-dong
Ich weiß es nicht. Hab das alles aus dem Internet zusammengepuzzelt.
http://msdn2.microsoft.com/en-us/library/aa767914.aspx (http://msdn2.microsoft.com/en-us/library/aa767914.aspx)
und
kb.mozillazine.org/Register_protocol (http://kb.mozillazine.org/Register_protocol)
Das mit dem @ habe ich von Mozillazine.
Kopier den Kode einfach und füge ihn in eine leere Textdatei. Diese Datei nennst du dann in blahblah.reg um. Pass noch den Pfad mit der .bat an. Und dann doppelklicke die Datei.
Titel: Re: point & click
Beitrag von: ding-dong am Samstag, 26. April 2008, 11:06
vielen dank für deine hilfe,  Andre!

ich habe das batch-programm erweitert, um files anzuzeigen, die nicht auf c: liegen.
das pdf und der source code [.ly] müssen aber auf dem richtigen drive liegen.

:: extract drive, path&filename, line number from the textdit command
@ECHO off
FOR /F "TOKENS=2 DELIMS=:" %%v IN ("%1") DO (@SET a=%%v)
  FOR /F "TOKENS=1 DELIMS=/" %%v IN ("%a%") DO (@SET dr=%%v)
FOR /F "TOKENS=3 DELIMS=:" %%v IN ("%1") DO (@SET pa=%%v)
FOR /F "TOKENS=4 DELIMS=:" %%v IN ("%1") DO (@SET ln=%%v)
"c:\programme\notepad++\notepad++.exe" -n%ln% "%dr%:%pa%"

in der tat müsste man noch einen editor wählen, der auf die entsprechende spalte springt!
gruss
Titel: Re: point & click
Beitrag von: Arnold am Montag, 10. Oktober 2011, 10:33
Hallo,

inspiriert von diesem Thema habe ich an meinem Windows-Rechner den bereits vorhandenen Programmaufruf ersetzt durch ein selbst geschreibenes C-Programm (anstelle des GUILE-Script-Starts den Lilypond in die Registry geschreiben hat).
Das Fenster zu finden, in dem die gesuchte Datei bereits geöffnet ist, und dieses in den Vordergrung zu holen, war ein Kinderspiel - den WindowsClass-Name des von mir benutzten Notepad ausfindig machen, dann alle diese Fenster nach einer passenden Kopfzeile absuchen.
Viel länger habe ich gesucht, bis ich den Sprung an die gewünschte Stelle hingebracht habe.
Ach ja, die LYW-Spezifika kommen aus der Zeit, da ich in einem Betriebssystem keine UTF8-Editor hatte, sondern stattdessen meine Dateien in UTF-16 geschrieben habe, per Programm die Ausgangsdatei und alle über \include angezogenen Dateien in UTF-8 ausgeleitet bzw. aktualisiert habe. Diese Quasi-Make-Prozedur konnte natürlich das Änderungsdatum aller Dateien auswerten und entscheiden, ob die PDF-Datei bereits aktuell ist. Heute liegt die Haupaufgabe darin, das betroffene Acrobat-Reader-Fenster zu schließen.
Aber jetzt erst einmal wieder zum Spung in den Texteditor:
/* LilyGotoEditor.c */
/*
 * Originally compiled with the 'free' Borland C++ command line compiler
 * which is: Borland C++ 5.5 for Win32 Copyright (c) 1993, 2000 Borland
 *           Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland
 *
 * command line: bcc32 -We LilyGotoEditor.c
 */

#define UNICODE

#include <windows.h>
#include <stdio.h>
#include <wchar.h>
#include <io.h>
#include <sys/types.h>
#include <sys/stat.h>


#define MyClassName L"LilyGotoEditorInquiryWin"
int ARGC;
wchar_t **ARGV;
int Tiefe = 1, Cntr, TCntr, VisibleOnly = 1;
int ScanModus = 0;
int wirdBeendet = 0;
int SuchTitelGrossKleinBeachten;
HWND GefundenesFenster = NULL;
wchar_t *SuchKlasse = NULL, *SuchTitel = NULL;
HINSTANCE myInst, myPrevInst;

int OrdinaryFileExists(wchar_t *F)
{ struct _stat st;
  if (_waccess(F, 4) < 0) return 0;
  if (_wstat(F, &st) < 0) return 0;
  if (st.st_mode & S_IFREG) return 1;
  return 0; // e.g. is a directory
}

BOOL CALLBACK MainWinEnumFunct(HWND hwnd, LPARAM lParam)
{ int ct, visi;
  wchar_t WindowTitle[270], ClassName[270];
  TCntr++;
  if (!IsWindow(hwnd)) return FALSE;
  WindowTitle[0] = ClassName[0] = 0;
  GetWindowText(hwnd, WindowTitle, 269);
  GetClassName(hwnd, ClassName, 269);
  WindowTitle[269] = 0; ClassName[269] = 0;
  visi = IsWindowVisible(hwnd);
  if (VisibleOnly && (!visi)) return TRUE;
  Cntr++;
  if (ScanModus) {
    for (ct = 0; ct < lParam; ct++) fprintf(stderr, "   ");
    fprintf(stderr, "[0x%.8lx]%s '%S' \"%S\"\n",
      (long) hwnd, VisibleOnly ? "" : visi ? " visib" : " invis",
      ClassName, WindowTitle);
  } else { /* SuchModus */
    if (!GefundenesFenster) {
      int passt = 1;
      if (SuchKlasse != NULL) {
        if (wcscmp(SuchKlasse, ClassName)) passt = 0;
      }
      if (SuchTitel != NULL) {
        if (SuchTitelGrossKleinBeachten) {
          if (wcscmp(SuchTitel, WindowTitle)) passt = 0;
        } else {
          if (_wcsicmp(SuchTitel, WindowTitle)) passt = 0;
        }
      }
      if (passt) GefundenesFenster = hwnd;
    }
  }
  /* sleep(1); */
  if (hwnd == NULL) return FALSE;
  if (Tiefe - 1 > lParam)
    EnumChildWindows(hwnd, MainWinEnumFunct, lParam + 1);
  return TRUE;
}

HWND SucheUnterFenster(HWND fenster, wchar_t *WindowClass, wchar_t *WindowTitle, int CaseSensitive)
{ ScanModus = 0;
  SuchKlasse = WindowClass; SuchTitel = WindowTitle;
  SuchTitelGrossKleinBeachten = CaseSensitive;
  GefundenesFenster = NULL;
  TCntr = Cntr = 0;
  EnumChildWindows(fenster, MainWinEnumFunct, 0L);
  return(GefundenesFenster);
}

HWND SucheFenster(wchar_t *WindowClass, wchar_t *WindowTitle, int CaseSensitive)
{ ScanModus = 0;
  SuchKlasse = WindowClass; SuchTitel = WindowTitle;
  SuchTitelGrossKleinBeachten = CaseSensitive;
  GefundenesFenster = NULL;
  TCntr = Cntr = 0;
  EnumWindows(MainWinEnumFunct, 0L);
  return(GefundenesFenster);
}

void ZaehleFenster(void)
{ ScanModus = 1;
  fprintf(stderr, "Tiefe = %d\n", Tiefe);
  TCntr = Cntr = 0;
  EnumWindows(MainWinEnumFunct, 0L);
  fprintf(stderr, "%d von %d Fenster bei Tiefe %d gelistet\n",
    Cntr, TCntr, Tiefe);
}


void SplitArg(wchar_t *arg, int *Line, int *Char, int *Column,
              wchar_t *Basename, wchar_t *FilePath, wchar_t *Lead)
{ int m, lg, ct, NameStart, NameEnd;
  NameStart = NameEnd = -1;
  Basename[0] = FilePath[0] = Lead[0] = 0;
  *Line = *Char = *Column = 0;
  m = 0; for (ct = wcslen(arg) - 1; ct >= 0; ct--) {
    if (arg[ct] == L':') {
      ++m;
      switch(m) {
        case 1: swscanf(&(arg[ct + 1]), L"%d", Column); break;
        case 2: swscanf(&(arg[ct + 1]), L"%d", Char); break;
        case 3: swscanf(&(arg[ct + 1]), L"%d", Line);
                NameEnd = ct; ct = -9;
      }
    }
  }
  for (ct = 0; (ct >= 0) && arg[ct]; ct++) {
    Lead[ct] = arg[ct]; Lead[ct + 1] = 0;
    if (arg[ct] == L':') {
      NameStart = ct + 1;
      if (arg[ct + 1] == L'/') {
        ++NameStart;
        wcscat(Lead, L"/");
        if (arg[ct + 2] == L'/') {
          ++NameStart;
          wcscat(Lead, L"/");
        }
      }
      ct = -9;
    }
  }
  lg = NameEnd - NameStart;
  if (lg > 0) {
    wcsncpy(FilePath, &(arg[NameStart]), lg);
    FilePath[lg] = 0;
    for (ct = 0; FilePath[ct]; ct++)
      if (FilePath[ct] == L'/') FilePath[ct] = L'\\';
  }
  for (ct = wcslen(FilePath) - 1; ct >= 0; ct--) {
    switch(FilePath[ct]) {
      case L'/': case L'\\': case L':':
        wcscpy(Basename, &(FilePath[ct + 1]));
        ct = -9;
    }
  }
  if (!Basename[0]) wcscpy(Basename, FilePath);
}

LRESULT CALLBACK
ShowInputs(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
  switch(message) {
    case WM_SYSKEYDOWN:
      fprintf(stderr, "\nWM_SYSKEYDOWN, wParam = 0x%.4x, lParam = 0x%.8lx", wParam, lParam);
      break;
    case WM_SYSKEYUP:
      fprintf(stderr, "\nWM_SYSKEYUP, wParam = 0x%.4x, lParam = 0x%.8lx", wParam, lParam);
      break;
    case WM_SYSCHAR:
      fprintf(stderr, "\nWM_SYSCHAR, wParam = 0x%.4x, lParam = 0x%.8lx", wParam, lParam);
      break;
    case WM_SYSDEADCHAR:
      fprintf(stderr, "\nWM_SYSDEADCHAR, wParam = 0x%.4x, lParam = 0x%.8lx", wParam, lParam);
      break;
    case WM_KEYDOWN:
      fprintf(stderr, "\nWM_KEYDOWN, wParam = 0x%.4x, lParam = 0x%.8lx", wParam, lParam);
      break;
    case WM_KEYUP:
      fprintf(stderr, "\nWM_KEYUP, wParam = 0x%.4x, lParam = 0x%.8lx", wParam, lParam);
      break;
    case WM_CHAR:
      fprintf(stderr, "\nWM_CHAR, wParam = 0x%.4x, lParam = 0x%.8lx", wParam, lParam);
      break;
    case WM_DEADCHAR:
      fprintf(stderr, "\nWM_DEADCHAR, wParam = 0x%.4x, lParam = 0x%.8lx", wParam, lParam);
      break;
    case WM_DESTROY:
      PostQuitMessage(0);
      wirdBeendet = 1;
      return 0;
  }
  return(DefWindowProc(hwnd, message, wParam, lParam));
}

void WatchKeyCodes(void)
{ MSG msg;
  int to;
  to = 100;
  fprintf(stderr, "\n\nSie haben jetzt ein paar Sekunden Zeit,\num Tastatureingaben im Fang-Fenster zu analysieren ...");
  do {
    if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
      TranslateMessage(&msg);
      DispatchMessage(&msg);
      to = 50;
    } else {
      --to; Sleep(50);
    }
  } while (to);
}

void ErzeugePruefFenster(void)
{ WNDCLASS wndclass;

  if (!myPrevInst) {
    wndclass.style = CS_HREDRAW | CS_VREDRAW;
    wndclass.lpfnWndProc = ShowInputs;
    wndclass.cbClsExtra = 0;
    wndclass.cbWndExtra = 0;
    wndclass.hInstance = myInst;
    wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wndclass.hCursor = LoadIcon(NULL, IDC_ARROW);
    wndclass.hbrBackground = (HBRUSH) COLOR_WINDOW - 1;
    wndclass.lpszMenuName = NULL;
    wndclass.lpszClassName = MyClassName;
    RegisterClass(&wndclass);
  }
  GefundenesFenster = CreateWindow(MyClassName,
                                   L"LilyGotoEditor - Tastenfänger",
                                   WS_OVERLAPPEDWINDOW,
                                   CW_USEDEFAULT, CW_USEDEFAULT,
                                   250, 80,
                                   NULL, NULL,
                                   myInst,
                                   NULL);
  fprintf(stderr, "\nCreated Window 0x%.8p\n", GefundenesFenster);
  ShowWindow(GefundenesFenster, SW_RESTORE);
  UpdateWindow(GefundenesFenster);
}

void SetupHelper(int level)
{ char Zeile[100];
  AllocConsole();
  fprintf(stderr, "Scanning Windows ...\n");
  Tiefe = level;
  while (1) {
    if (wirdBeendet) { GefundenesFenster = NULL; wirdBeendet = 0; }
    if (GefundenesFenster == NULL) ErzeugePruefFenster();
    ZaehleFenster();
    SetFocus(GefundenesFenster);
    WatchKeyCodes();
    fprintf(stderr, "\nBitte RETURN um Scan zu wiederholen ..");
    fprintf(stderr, "\n(Fenster schliessen um zu beenden)    ");
    fgets(Zeile, 100, stdin);
  }
}

void SendKeyStrokeInputs(wchar_t *s)
{ INPUT inputToSend[100];
  wchar_t cmd[32];
  long lParam, wParam;
  int lg, ct;
  wchar_t info[1000];
  // swprintf(info, L"SendKeyStrokeInputs(\"%s\")\n", s);
  // fprintf(stderr, "SendKeyStrokeInputs(\"%S\")\n", s);
  lg = ct = 0;
  while (s[ct] && (lg < 100)) {
    if (s[ct] == L'(') {
      lParam = wParam = 0; cmd[0] = 0;
      swscanf(&(s[ct + 1]), L"%s%x%x", cmd, &wParam, &lParam);
      if (!_wcsicmp(cmd, L"KEYDOWN")) {
        inputToSend[lg].ki.dwFlags = 0;
        goto keyupdown;
      } else if (!_wcsicmp(cmd, L"KEYUP")) {
        inputToSend[lg].ki.dwFlags = KEYEVENTF_KEYUP;
keyupdown:
        inputToSend[lg].ki.wVk = wParam;
        inputToSend[lg].ki.wScan = (lParam & 0x1ff0000) >> 16;
        inputToSend[lg].ki.time = 0;
        inputToSend[lg].ki.dwExtraInfo = 0;
        ++lg;
      }
      while (s[ct] && (s[ct] != L')')) ++ct;
    }
    if (s[ct]) ct++;
  }

  if (lg) SendInput(lg, inputToSend, sizeof(INPUT));
  // fprintf(stderr, "%d Input-Aktionen gesendet ...\n", lg);
  // swprintf(&(info[wcslen(info)]), L"\n%d Input-Aktionen waren im Sendepuffer", lg);
  for (ct = 0; ct < lg; ct++) {
    swprintf(&(info[wcslen(info)]), L"\n { %ld, %lx, %lx }",
      (long) inputToSend[ct].ki.dwFlags,
      (long) inputToSend[ct].ki.wVk,
      (long) inputToSend[ct].ki.wScan);
  }
  // MessageBox(NULL, info, L"TRACE", MB_ICONINFORMATION | MB_OK);
}

void SendUnicodeKeyInput(wchar_t *s)
{ INPUT inputToSend[100];
  int lg, ct;
  lg = wcslen(s);
  if (lg > 100) lg = 100;
  if (!s) return;
  for (ct = 0; ct < lg; ct++) {
    inputToSend[ct].type = INPUT_KEYBOARD;
    inputToSend[ct].ki.wVk = 0;
    inputToSend[ct].ki.wScan = s[ct];
    inputToSend[ct].ki.dwFlags = KEYEVENTF_UNICODE;
    inputToSend[ct].ki.time = 0;
    inputToSend[ct].ki.dwExtraInfo = 0;
  }
  SendInput(lg, inputToSend, sizeof(INPUT));
}

void LilyGotoEditor(wchar_t *arg)
{ int Line, Char, Column;
  int m, ct, NameStart, NameEnd;
  int erg1, /* erg2, */ erg3 /*, erg4 */ ;
  wchar_t Basename[MAX_PATH], FilePath[MAX_PATH], Lead[MAX_PATH];
  HWND fenster, fenster2, fenster3;
  wchar_t FensterTitel[MAX_PATH + 100];

  // 1. Die Aufrufzeile entschlüsseln ...
  SplitArg(arg, &Line, &Char, &Column, Basename, FilePath, Lead);
  /* { wchar_t InfoText[1000];
    swprintf(InfoText, L"Aufrufparameter = »%s«", arg);
    swprintf(&(InfoText[wcslen(InfoText)]), L"\nLine = %d\nChar = %d\nColumn = %d", Line, Char, Column);
    swprintf(&(InfoText[wcslen(InfoText)]), L"\nBasename = »%s«\nFilePath = »%s«\nLead = »%s«",
      Basename, FilePath, Lead);
    MessageBox(NULL, InfoText, L"LilyGotoEditor", MB_ICONINFORMATION | MB_OK);
  } */
  if (Line <= 0) {
    wchar_t InfoText[1000];
    swprintf(InfoText, L"In der Aufrufzeile (»%s«) konnte keine gültige Zeilennummer gefunden werden!\r\n"
      L"\r\nAlso kann auch nicht dorthin gesprungen werden.", arg);
    MessageBox(NULL, InfoText, L"LilyGotoEditor", MB_ICONERROR | MB_OK);
    return;
  }

  // 2. Suche, ob schon eine Editor-Fenter offen ist - ich benutze »Notepad«
  swprintf(FensterTitel, L"%sw - Editor", Basename);                    // LYW - special
  if ((fenster = SucheFenster(L"Notepad", FensterTitel, 0)) == NULL) {  // LYW - special
    swprintf(FensterTitel, L"%s - Editor", Basename);
    fenster = SucheFenster(L"Notepad", FensterTitel, 0);
  }                                                                     // LYW - special
  /* { wchar_t InfoText[1000];
    swprintf(InfoText, L"FensterTitel = »%s«\nFenster = 0x%p", FensterTitel, fenster);
    MessageBox(NULL, InfoText, L"LilyGotoEditor", MB_ICONINFORMATION | MB_OK);
  } */

  // 3. Falls kein Editor-Fenster offen ist, die Datei öffnen (und Tschüß, klick bitte nochmal)
  if (fenster == NULL) {
    wchar_t InfoText[1000];
    swprintf(InfoText, L"Datei »%s« ist offenbar noch nicht mit »Notepad« geöffnet!\r\n\r\n"
                       L"Bitte die Datei\r\n»%s«\r\nöffnen (z. Bsp. durch OK) und dann die Aktion wiederholen.",
      Basename, FilePath);
    if (MessageBox(NULL, InfoText, L"LilyGotoEditor", MB_ICONEXCLAMATION | MB_OKCANCEL) == IDOK) {
      swprintf(InfoText, L"%sw", FilePath);
      if (OrdinaryFileExists(InfoText))                             // LYW - special
        swprintf(InfoText, L"start notepad \"%sw\"", FilePath);     // LYW - special
       else {                                                       // LYW - special
        if (!OrdinaryFileExists(FilePath)) {
          swprintf(InfoText, L"Leider keine Datei »%s« gefunden!\r\n\r\nAlso kann ich sie auch nicht öffnen.", FilePath);
          MessageBox(NULL, InfoText, L"LilyGotoEditor", MB_ICONERROR | MB_OK);
          return;
        }
        swprintf(InfoText, L"start notepad \"%s\"", FilePath);
      }                                                             // LYW - special
      _wsystem(InfoText);
    }
    return;
  }

  // 4. Das Editorfenster i_r_g_e_n_d_w_i_e nach vorne bringen
  /* erg4 = */ ShowWindow(fenster, SW_RESTORE);
  erg1 = SetForegroundWindow(fenster);
  /* erg2 = */ SetWindowPos(fenster, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
  erg3 = (SetFocus(fenster) == NULL);
  BringWindowToTop(fenster);
  /* { wchar_t InfoText[1000];
    swprintf(InfoText, L"ShowWindow(): %d\nSetForgroundWindow(): %d\nSetWindowPos(): %d\nSetFocus(): %d",
      erg4, erg1, erg2, erg3);
    MessageBox(NULL, InfoText, L"LilyGotoEditor", MB_ICONINFORMATION | MB_OK);
  } */
  if (!erg1 || !erg3) {
    wchar_t InfoText[1000];
    swprintf(InfoText, L"Habe Probleme festgestellt beim Versuch, das Editier-Fenster der Datei »%s« in den Vordergund zu rufen!", Basename);
    MessageBox(NULL, InfoText, L"LilyGotoEditor", MB_ICONINFORMATION | MB_OK);
    return;
  }

  Sleep(700);  // 0,7 Sekunden Verschnaufpause
 
  // 5. Dialog öffnen »zu Zeile springen« - diesen Einsprung habe ich durch probieren gefunden
  PostMessage(fenster, WM_COMMAND, 24, (LPARAM) Line);

  // 6. Warten bis der Dialog bereit ist (ein anderes Fenster aktiv ist)
  for (ct = 30; ct > 0; ct--) {
    fenster2 = GetForegroundWindow();
    if ((fenster2 != NULL) && (fenster2 != fenster)) ct = 0;
     else Sleep(25);
  }
  Sleep(100);

  // 7. Meine Zeilennummer übergeben
  { wchar_t Nr[50]; swprintf(Nr, L"%d", Line); SendUnicodeKeyInput(Nr); }
  Sleep(300);

  // 8. Den »Wechseln«-Button des Dialogs suchen ...
  fenster3 = SucheUnterFenster(fenster2, L"Button", L"Wechseln", 1);

  // 9. ... und dem einen Mausklick vorgaukeln
  if (fenster3 != NULL) {
    SendMessage(fenster3, WM_LBUTTONDOWN, MK_LBUTTON, 0x00050005);
    SendMessage(fenster3, WM_LBUTTONUP, 0, 0x00050005);
  }
  /*
  { wchar_t M[1000]; swprintf(M, L"fenster2 = 0x%p\nfenster = 0x%p\nfenster3 = 0x%p", fenster2, fenster, fenster3);
    MessageBox(NULL, M, L"TRACE", MB_ICONINFORMATION | MB_OK);
  }
  */
  Sleep(350);

  // 10. Und jetzt das eigentliche Text-Edit-Fenster des Editors suchen
  //     - es gibt derer drei. Hoffentlich bleibt die Reihenfolge immer gleich,
  //       sonst muß ich vielleicht auch noch Fenstergröße und -position auswerten.
  fenster2 = SucheUnterFenster(fenster, L"Edit", L"", 1);
  if (fenster2 == NULL) fenster2 = fenster;

  // 11. Und dem eine ausreichende Anzahl an »Cursor Rechts«-Tastendrücken vorgaukeln
  for (ct = 0; ct < Char; ct++) {
    SendMessage(fenster2, WM_KEYDOWN, 0x0027, 0x014d0001);
    SendMessage(fenster2, WM_KEYUP, 0x0027, 0xc14d0001);
  }

  // Fine. Wenn alles gutgegangen ist, sind wir im Editor an der gewünschten Position angekommen.

  // Fazit: War wesentlich widerspenstiger als ich es mir dachte.
}





int WINAPI WinMain(HINSTANCE hInstance,
   HINSTANCE hPrevInstance,
   LPSTR plszCmdParam,
   int nCmdShow)
{ int ct, p;
  ARGV = CommandLineToArgvW(GetCommandLineW(), &ARGC);
  myInst = hInstance;
  myPrevInst = hPrevInstance;

  // AllocConsole();
 
  for (ct = 1; ct < ARGC; ct++) {
    if (ARGV[ct][0] == L'-') {
      for (p = 1; ARGV[ct][p]; p++) switch(ARGV[ct][p]) {
        case '1': SetupHelper(1); break;
        case '2': SetupHelper(2); break;
        case '3': SetupHelper(3); break;
        case '4': SetupHelper(4); break;
      }
    } else {
      LilyGotoEditor(ARGV[ct]);
    }
  }
  // Sleep(15000);
  return 0;
}
Natürlich ist diese Lösung maßgeschneidert auf mein Setup und deshalb selten von anderen ohne Änderung nutzbar. Daher macht es auch keinen Sinn, eine EXE-Datei anzuhängen.
Und wirklich tragfähig wäre eine solche Lösung erst, wenn es einen »allgemein akzeptierten Schnipsel-Jäger-Editor« für Lilypond gäbe, also so etwas wie eine »Integrierte Entwicklungsumgebung« (mit Verwendungsnachweis), die dann auch eine vordefinierte Schnittstelle zum von außen initiierten Springen an eine bestimmte Position bietet.