Windows Rechner (Calc)

Fragen rund um diverse Windows-Versionen, ihr Verhalten unter Xbase++ und den Umgang mit der API

Moderator: Moderatoren

Antworten
Benutzeravatar
Koverhage
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2479
Registriert: Fr, 23. Dez 2005 8:00
Wohnort: Aalen
Hat sich bedankt: 110 Mal
Danksagung erhalten: 3 Mal
Kontaktdaten:

Windows Rechner (Calc)

Beitrag von Koverhage »

Hallo,

ich möchte in der Xbase++ Anwendung die Möglichkeit geben, den Windows Rechner aufzurufen
und das Ergebnis zu übernehmen.
Es gibt wenn ich das so sehe 2 Möglichkeiten:
1. Der Anwender kopiert das Ergebnis in die Zwischenablage
2. mit der SendMessage Function.
Die 2. Möglichkeit verstehe ich nicht, denn der Anwender ruft den Rechner auf, führt Berchnungen durch, bis er das Ergebnis hat
und schließt dann den Rechner, wie soll die Funktion dann das Ergebnis finden ?


hier mal der VB Code für die 2. Möglichkeit den ich im Netz gefunden habe.

Hat das schon jemand gemacht und gelöst ?

Option Explicit

Private Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" ( _
ByVal hWnd As Long, _
ByVal Msg As Long, _
wParam As Any, _
lParam As Any) As Long
Private Declare Function FindWindowEx Lib "user32.dll" Alias "FindWindowExA" ( _
ByVal hwndParent As Long, _
ByVal hwndChildAfter As Long, _
ByVal lpszClass As String, _
ByVal lpszWindow As String) As Long

Private Const WM_GETTEXT As Long = &HD
Private Const WM_GETTEXTLENGTH As Long = &HE

Private Sub Command1_Click()
Dim CalcHwnd As Long ' Calculator Handle
Dim Edithwnd As Long ' Edit window Handle
Dim slength As Long ' Länge des Textes im gefundenen Fenster
Dim wintext As String ' Textinhalt des Fensters
Dim retval As Long ' Ergebnis

CalcHwnd = FindWindowEx(0, 0, "SciCalc", "Calculator") '//Calculator Handle
Edithwnd = FindWindowEx(CalcHwnd, 0, "Edit", vbNullString) '//Edit window Handle

If Edithwnd = 0 Then
Debug.Print "Edit box wurde nicht gefunden"
Else
slength = SendMessage(Edithwnd, WM_GETTEXTLENGTH, ByVal CLng(0), ByVal CLng(0)) + 1

wintext = Space$(slength)

retval = SendMessage(Edithwnd, WM_GETTEXT, ByVal slength, ByVal wintext)

wintext = Left$(wintext, retval)

'//Das Resultat
Label1.Caption = wintext

End If

End Sub
Gruß
Klaus
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12947
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 20 Mal
Danksagung erhalten: 51 Mal

Re: Windows Rechner (Calc)

Beitrag von AUGE_OHR »

Koverhage hat geschrieben: CalcHwnd = FindWindowEx(0, 0, "SciCalc", "Calculator") '//Calculator Handle
Edithwnd = FindWindowEx(CalcHwnd, 0, "Edit", vbNullString) '//Edit window Handle

retval = SendMessage(Edithwnd, WM_GETTEXT, ByVal slength, ByVal wintext)
ich habe mal das daraus gemacht

Code: Alles auswählen

nCalcHwnd := DllCall("User32.dll",DLL_STDCALL, "FindWindowExA", 0, 0, "SciCalc", "Rechner")
nEdithwnd := DllCall("User32.dll",DLL_STDCALL, "FindWindowExA",nCalcHwnd, 0,"Edit","")
nLength := SendMessageA(nEdithwnd, WM_GETTEXTLENGTH, 0, 0) +1
cText   := SPACE(nLength) + Chr(0)
cString := SendMessageA(nEdithwnd, WM_GETTEXT, @nLength, @cText)
ALTD()
cText := STRTRAN(cText,CHR(0),"")
ich habe nEdithwnd mit WinID überprüft und sie stimmt überein.
Leider bekomme ich für cString nur die Länge LEN(cText) zurück ...

noch ein Versuch mit Notepad

Code: Alles auswählen

nEdithwnd := DllCall("User32.dll",DLL_STDCALL, "FindWindowExA",nNoteHwnd, 0,"Edit","")
nLength := SendMessageA(nEdithwnd, WM_GETTEXTLENGTH, 0, 0) +1
cText   := SPACE(nLength) + Chr(0)
cString := SendMessageA(nEdithwnd, WM_GETTEXT, @nLength, @cText)
ALTD()
cText := STRTRAN(cText,CHR(0),"")
dito nur die Länge des Text :(
gruss by OHR
Jimmy
Günter Beyes
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 315
Registriert: Mo, 16. Okt 2006 13:04
Wohnort: Region Stuttgart

Re: Windows Rechner (Calc)

Beitrag von Günter Beyes »

Hallo,

@Jimmy,

Code: Alles auswählen

SendMessageA(nEdithwnd, WM_GETTEXT, @nLength, @cText)
nLength darf nicht by reference übergeben werden.

@Klaus,

du kannst die Abfrage in eine Schleife verpacken, die solange läuft, bis Calc beendet wird.

Gruß,
Günter

Code: Alles auswählen

#include "dll.ch"

#define WM_GETTEXT              0x000D
#define WM_GETTEXTLENGTH        0x000E

proc main()

local nCalcHwnd := DllCall("User32.dll",DLL_STDCALL, "FindWindowExA", 0, 0, "SciCalc", "Rechner")
local nEdithwnd := DllCall("User32.dll",DLL_STDCALL, "FindWindowExA",nCalcHwnd, 0,"Edit","")
local cResult   := ""
local cPrevious := ""
local nLength
local cText
local rc

local SendMessageA := DllPrepareCall( "user32.dll", DLL_STDCALL, "SendMessageA" )
local IsWindow     := DllPrepareCall( "user32.dll", DLL_STDCALL, "IsWindow" )
 
set charset to ansi

if nEdithwnd = 0
   Msgbox("Der Rechner läuft nicht", "Information" )
   return
endif

Do while DllExecuteCall( IsWindow, nEdithwnd ) != 0 // Ist das handle ungültig, wurde calc beendet.
    nLength := DllExecuteCall( SendMessageA, nEdithwnd, WM_GETTEXTLENGTH, 0, 0) +1
    cText   := SPACE(nLength)
    rc      := DllExecuteCall( SendMessageA, nEdithwnd, WM_GETTEXT, nLength, @cText)
    cResult := STRTRAN(cText,CHR(0),"")
    if ! cResult == cPrevious
      ? cResult
      cPrevious := cResult
    endif
    sleep(10)
enddo

msgbox( cResult, "Rechenergebnis" )

return
Benutzeravatar
Koverhage
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2479
Registriert: Fr, 23. Dez 2005 8:00
Wohnort: Aalen
Hat sich bedankt: 110 Mal
Danksagung erhalten: 3 Mal
Kontaktdaten:

Re: Windows Rechner (Calc)

Beitrag von Koverhage »

Hallo Günter,

super Danke.

Dann kann ich doch wenn nEdithwnd = 0 ist, den Rechner mit ShellExecuteA aufrufen
verarbeit ShellExexuteA die folgende Angabe ?
%windir%\system32\calc.exe
Gruß
Klaus
Günter Beyes
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 315
Registriert: Mo, 16. Okt 2006 13:04
Wohnort: Region Stuttgart

Re: Windows Rechner (Calc)

Beitrag von Günter Beyes »

Hallo Klaus,

da bin ich nicht sicher; eventuell funktioniert es aber auch ohne Pfadangabe, wenn %windir%\system32 im PATH angegeben ist. Oder Getenv( "SystemRoot" ) + "\system32" verwenden.

Wenn man in calc die Ansicht (Standard/Wissenschaftlich) umschaltet, wird das Handle ungültig (und damit die Abfrageschleife beendet), weil das calc-Fenster dabei komplett neu aufbaut wird. Die Abfrageschleife müsste deshalb noch etwas geändert werden.

Gruß,
Günter

Code: Alles auswählen

lRunning := ( DllExecuteCall( IsWindow, nEdithwnd ) != 0 )

if ! lRunning
   Msgbox("Der Rechner läuft nicht", "Information" )
   return
endif

Do while lRunning
    // Calc-Edit abfragen
    (...)
    
    lRunning := ( DllExecuteCall( IsWindow, nEdithwnd ) != 0 )
    if ! lRunning
       // Ist das handle ungültig, wurde calc entweder beendet 
       // oder die Ansicht (Standard/Wissenschaftlich) umgeschaltet.
       // Um das festzustellen, wird versucht, das handle zu aktualisieren.
       sleep( 10 ) 
       nCalcHwnd := DllCall("User32.dll",DLL_STDCALL, "FindWindowExA", 0, 0, "SciCalc", "Rechner")
       nEdithwnd := DllCall("User32.dll",DLL_STDCALL, "FindWindowExA",nCalcHwnd, 0,"Edit","")
       lRunning  := ( DllExecuteCall( IsWindow, nEdithwnd ) != 0 )
    endif
enddo
Benutzeravatar
Koverhage
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2479
Registriert: Fr, 23. Dez 2005 8:00
Wohnort: Aalen
Hat sich bedankt: 110 Mal
Danksagung erhalten: 3 Mal
Kontaktdaten:

Re: Windows Rechner (Calc)

Beitrag von Koverhage »

Hallo Günter,

habe das jetzt so, bekomme aber leider kein Ergebnis.
Gruß
Klaus

Code: Alles auswählen

proc rechner()

local nCalcHwnd := DllCall("User32.dll",DLL_STDCALL, "FindWindowExA", 0, 0, "SciCalc", "Rechner")
local nEdithwnd := DllCall("User32.dll",DLL_STDCALL, "FindWindowExA",nCalcHwnd, 0,"Edit","")
local cResult   := ""
local cPrevious := ""
local nLength
local cText
local rc
local cProgPath :=  GetEnv("windir")+"\system32\calc.exe"

local SendMessageA := DllPrepareCall( "user32.dll", DLL_STDCALL, "SendMessageA" )
local IsWindow     := DllPrepareCall( "user32.dll", DLL_STDCALL, "IsWindow" )
local lRunning := ( DllExecuteCall( IsWindow, nEdithwnd ) != 0 )


//set charset to ansi

if ! lRunning
   IF ShellExecute(NIL, SHELL_OPEN, cProgPath,,,SW_SHOW)
      do while nEdithwnd = 0
         nCalcHwnd := DllCall("User32.dll",DLL_STDCALL, "FindWindowExA", 0, 0, "SciCalc", "Rechner")
         nEdithwnd := DllCall("User32.dll",DLL_STDCALL, "FindWindowExA",nCalcHwnd, 0,"Edit","")
         sleep(10)
      enddo
      lRunning := ( DllExecuteCall( IsWindow, nEdithwnd ) != 0 )
   ENDIF
endif

Do while lRunning
    // Calc-Edit abfragen
    nLength := DllExecuteCall( SendMessageA, nEdithwnd, WM_GETTEXTLENGTH, 0, 0) +1
    cText   := SPACE(nLength)
    rc      := DllExecuteCall( SendMessageA, nEdithwnd, WM_GETTEXT, nLength, @cText)
    cResult := STRTRAN(cText,CHR(0),"")
    if ! cResult == cPrevious
        cPrevious := cResult
    endif


    lRunning := ( DllExecuteCall( IsWindow, nEdithwnd ) != 0 )
    if ! lRunning
       // Ist das handle ungültig, wurde calc entweder beendet
       // oder die Ansicht (Standard/Wissenschaftlich) umgeschaltet.
       // Um das festzustellen, wird versucht, das handle zu aktualisieren.
       sleep( 10 )
       nCalcHwnd := DllCall("User32.dll",DLL_STDCALL, "FindWindowExA", 0, 0, "SciCalc", "Rechner")
       nEdithwnd := DllCall("User32.dll",DLL_STDCALL, "FindWindowExA",nCalcHwnd, 0,"Edit","")
       lRunning  := ( DllExecuteCall( IsWindow, nEdithwnd ) != 0 )
    endif
enddo


msgbox( cResult, "Rechenergebnis" )

return
Gruß
Klaus
Günter Beyes
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 315
Registriert: Mo, 16. Okt 2006 13:04
Wohnort: Region Stuttgart

Re: Windows Rechner (Calc)

Beitrag von Günter Beyes »

Hallo Klaus,

Code: Alles auswählen

IF ShellExecute(NIL, SHELL_OPEN, cProgPath,,,SW_SHOW)
Hmm. Wie sind SHELL_OPEN und SW_SHOW definiert, und wie sieht der Code von ShellExecute() aus?

Das folgende funktioniert hier nämlich.

Gruß,
Günter

Code: Alles auswählen

   #define SW_SHOW        5

   cProgPath :=  GetEnv("windir")+"\system32\calc.exe"
   rc := ShellExecuteA( 0, 0, cProgPath, 0, 0, SW_SHOW )
   if rc < 32
      Msgbox( cProgPath + " kann nicht ausgeführt werden. Fehlercode " + var2char( rc), "Information" )
      return
   else
      sleep(10)
      nCalcHwnd := DllCall("User32.dll",DLL_STDCALL, "FindWindowExA", 0, 0, "SciCalc", "Rechner")
      nEdithwnd := DllCall("User32.dll",DLL_STDCALL, "FindWindowExA",nCalcHwnd, 0,"Edit","")
      lRunning := ( DllExecuteCall( IsWindow, nEdithwnd ) != 0 )
  
      Msgbox( cProgPath + " gestartet, Rückgabewert " + var2char( rc ) + ;
              " Edit-Handle " + var2char( nEdithwnd ), "Information" )
   endif   

   DLLFUNCTION ShellExecuteA( hwnd, lpOperation, lpFile, lpParameters, lpDirectory, nShowCmd ) ;
   using stdcall from shell32.dll
Benutzeravatar
Koverhage
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2479
Registriert: Fr, 23. Dez 2005 8:00
Wohnort: Aalen
Hat sich bedankt: 110 Mal
Danksagung erhalten: 3 Mal
Kontaktdaten:

Re: Windows Rechner (Calc)

Beitrag von Koverhage »

Hallo Günter,

#define SHELL_OPEN "open"
#define SW_NORMAL 1


FUNC ShellExecute(nWhnd, cMode, cFile, cPara, cDir, nShow )
Local cBin := DllPrepareCall( "SHELL32.DLL", DLL_STDCALL, "ShellExecuteA")
Local nErg
SET DEFAULT to nWhnd to AppDesktop():GetHWnd()
SET DEFAULT to cMode to SHELL_OPEN
SET DEFAULT to nShow to SW_NORMAL

cPara := iif( empty(cPara), cPara := 0, '"' + cPara +'"')
iif( empty(cDir), cDir:=0, )
nErg := DllExecuteCall(cBin, nWhnd, @cMode, @cFile, @cPara, @cDir, nShow)

RETURN ( IIF( nErg <= 32, .F., .T.))

Gruß
Klaus
Gruß
Klaus
Günter Beyes
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 315
Registriert: Mo, 16. Okt 2006 13:04
Wohnort: Region Stuttgart

Re: Windows Rechner (Calc)

Beitrag von Günter Beyes »

Hallo Klaus,

damit funktioniert das hier auch.

Lass dir doch mal den Rückgabewert von DllExecuteCall(cBin, nWhnd, @cMode, @cFile, @cPara, @cDir, nShow) anzeigen.

Gruß,
Günter
Benutzeravatar
Koverhage
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2479
Registriert: Fr, 23. Dez 2005 8:00
Wohnort: Aalen
Hat sich bedankt: 110 Mal
Danksagung erhalten: 3 Mal
Kontaktdaten:

Re: Windows Rechner (Calc)

Beitrag von Koverhage »

Hallo Günter,

der Rückgabewert ist 42.

Gruß
Klaus
Gruß
Klaus
Benutzeravatar
Koverhage
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2479
Registriert: Fr, 23. Dez 2005 8:00
Wohnort: Aalen
Hat sich bedankt: 110 Mal
Danksagung erhalten: 3 Mal
Kontaktdaten:

Re: Windows Rechner (Calc)

Beitrag von Koverhage »

Ich gebe auf. Ich bekomme keinen Rückgabewert,
es funktioniert soweit alles, ich rufe den Rechner auf, wenn ich den beende
kommt auch die Box mit dem nicht vorhandenen Ergebnis.

Habe auch mal versucht, mit WM_SETTEXT eine Vorgabe an den Rechner
zu senden, aber auch das klappt nicht.
Gruß
Klaus
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12947
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 20 Mal
Danksagung erhalten: 51 Mal

Re: Windows Rechner (Calc)

Beitrag von AUGE_OHR »

Koverhage hat geschrieben:Ich gebe auf. Ich bekomme keinen Rückgabewert,
es funktioniert soweit alles, ich rufe den Rechner auf, wenn ich den beende
kommt auch die Box mit dem nicht vorhandenen Ergebnis.
hm ... bei mir klappt es sehr schön.

Code: Alles auswählen

#include "Xbp.ch"
#include "DLL.ch"
#include "Appevent.ch"

#define WM_GETTEXT          0x000D
#define WM_GETTEXTLENGTH    0x000E
#define WM_CLOSE            0x0010

PROCEDURE APPSYS
RETURN

PROCEDURE MAIN
LOCAL nEvent, mp1, mp2, oXbp
LOCAL cVarA := "1234.12", cVarB := "9999999.99"
LOCAL oDlg,oSLE1,oSLE2

   oDlg          := XbpDialog():new( ,, {50,30}, {300,200} )
   oDlg:title    := "SLECALC"
   oDlg:tasklist := .T.
   oDlg:create()

   oSLE1              := XbpSLE():new(oDlg:drawingArea , , {100,100}, {100,30} )
   oSLE1:autoTab      := .T.
   oSLE1:bufferLength := 12
   oSLE1:dataLink := {|x| IIf( x==NIL, cVarA, cVarA := x ) }
   oSLE1:create()
   oSLE1:setData()
   oSLE1:killInputFocus := { |x,y,oSLE| NIL }
   oSLE1:setInputFocus  := { |x,y,oSLE| GetFromCalc(oSLE1) }

   oSLE2              := XbpSLE():new(oDlg:drawingArea , , {100, 50}, {100,30} )
   oSLE2:tabStop      := .T.
   oSLE2:bufferLength := 12
   oSLE2:dataLink := {|x| IIf( x==NIL, cVarB, cVarB := x ) }
   oSLE2:create()
   oSLE2:setData()
   oSLE2:killInputFocus := { |x,y,oSLE| NIL }
   oSLE2:setInputFocus  := { |x,y,oSLE| GetFromCalc(oSLE2) }

   CenterControl(oDlg)
   setappwindow(oDlg)
   setappfocus(oSLE1)

   nEvent := 0
   DO WHILE nEvent <> xbeP_Close
      nEvent := AppEvent( @mp1, @mp2, @oXbp )
      oXbp:handleEvent( nEvent, mp1, mp2 )
   ENDDO

RETURN

PROCEDURE GetFromCalc(oSLE)
LOCAL nCalcHwnd 
LOCAL nEdithwnd
LOCAL cString
LOCAL nLength
LOCAL cText    := ""
LOCAL SendMessageA := DllPrepareCall( "user32.dll", DLL_STDCALL, "SendMessageA" )

   nCalcHwnd := DllCall("User32.dll",DLL_STDCALL,"FindWindowA",0,"Rechner"+Chr(0) )

   IF .NOT. nCalcHwnd > 0
      RunShell( "","CALC.EXE", .T.)
      RETURN
   ENDIF

   IF nCalcHwnd > 0
      nCalcHwnd := DllCall("User32.dll",DLL_STDCALL, "FindWindowExA", 0, 0, "SciCalc", "Rechner")
      nEdithwnd := DllCall("User32.dll",DLL_STDCALL, "FindWindowExA",nCalcHwnd, 0,"Edit","")

      nLength   := DllExecuteCall(SendMessageA,nEdithwnd, WM_GETTEXTLENGTH, 0, 0) +1
      cText     := SPACE(nLength) + Chr(0)
      cString   := DllExecuteCall(SendMessageA,nEdithwnd, WM_GETTEXT, nLength, @cText)
      cText     := STRTRAN(cText,CHR(0),"")

      IF VAL(cText) > 0
         oSLE:setdata(cText)
         // Rechner "löschen"/"schliessen"
         DllExecuteCall(SendMessageA,nCalcHwnd,WM_CLOSE,0,0)
      ENDIF
   ENDIF

RETURN
gruss by OHR
Jimmy
Benutzeravatar
Koverhage
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2479
Registriert: Fr, 23. Dez 2005 8:00
Wohnort: Aalen
Hat sich bedankt: 110 Mal
Danksagung erhalten: 3 Mal
Kontaktdaten:

Re: Windows Rechner (Calc)

Beitrag von Koverhage »

Hallo Günter und Jimmy,

danke euch beiden.

Bin jetzt soweit gekommen.
1. Ich darf cResult nicht nehmen wenn es empty ist (immer beim Schließen vom Rechner)
2. Ich kann einen String mit WM_SETTEXT übergeben, nützt mir zwar nichts, da der Rechner ja im dec Modus
nur Zahlen nimmt.
3. Kann den Rechner auch mit WM_CLOSE beenden , wenn ich einen Wert habe.

Primär waren es 2 Probleme, wobei eines immer noch besteht.
Problem wie in Punkt eins kann ich abfangen und klappt dann auch.

Das 2. Problem: Unter Windows 7 64-bit funktioniert das ganze nicht, da nCalcHwnd 0 ist.

Jimmy hast Du das auch mal unter Windows 7 64-bit laufen lassen ?

Code: Alles auswählen

proc rechner()

local nCalcHwnd := DllCall("User32.dll",DLL_STDCALL, "FindWindowExA", 0, 0, "SciCalc", "Rechner")
local nEdithwnd := DllCall("User32.dll",DLL_STDCALL, "FindWindowExA",nCalcHwnd, 0,"Edit","")
local cResult   := ""
local cPrevious := ""
local cInitValue := "123456789"+chr(0)
local nLength
local cText
local rc
local cProgPath :=  GetEnv("windir")+"\system32\calc.exe"

local SendMessageA := DllPrepareCall( "user32.dll", DLL_STDCALL, "SendMessageA" )
local IsWindow     := DllPrepareCall( "user32.dll", DLL_STDCALL, "IsWindow" )
// Prfen ob nEdithwnd ein gltiges Fenbster ist
local lRunning := ( DllExecuteCall( IsWindow, nEdithwnd ) != 0 )

//local nCharSet := SET(_SET_CHARSET,ANSI)



if ! lRunning
   IF ShellExecute(NIL, SHELL_OPEN, cProgPath,,,SW_SHOW)
      do while nEdithwnd = 0
         // alt Rechner
         nCalcHwnd := DllCall("User32.dll",DLL_STDCALL, "FindWindowExA", 0, 0, "SciCalc", "Rechner")
         nEdithwnd := DllCall("User32.dll",DLL_STDCALL, "FindWindowExA",nCalcHwnd, 0,"Edit","")
         sleep(10)
      enddo
      lRunning := ( DllExecuteCall( IsWindow, nEdithwnd ) != 0 )
   ENDIF
endif
//msgbox(str(nCalchwnd)+"|"+str(nedithwnd))

DllExecuteCall( SendMessageA, nEdithwnd, WM_SETTEXT, 0, cInitValue)

Do while lRunning
    // Calc-Edit abfragen
    nLength := DllExecuteCall( SendMessageA, nEdithwnd, WM_GETTEXTLENGTH, 0, 0) +1
    cText   := SPACE(nLength)
    rc      := DllExecuteCall( SendMessageA, nEdithwnd, WM_GETTEXT, nLength, @cText)
    cResult := STRTRAN(cText,CHR(0),"")
    if !empty(cResult)
    if ! cResult == cPrevious
        cPrevious := cResult
    endif
    endif
    if val(cResult) > 0
//       DllExecuteCall( SendMessageA, nCalcHwnd, WM_CLOSE, 0, 0)
    endif



    lRunning := ( DllExecuteCall( IsWindow, nEdithwnd ) != 0 )
    if ! lRunning
       // Ist das handle ungültig, wurde calc entweder beendet
       // oder die Ansicht (Standard/Wissenschaftlich) umgeschaltet.
       // Um das festzustellen, wird versucht, das handle zu aktualisieren.
       sleep( 10 )
       nCalcHwnd := DllCall("User32.dll",DLL_STDCALL, "FindWindowExA", 0, 0, "SciCalc", "Rechner")
       nEdithwnd := DllCall("User32.dll",DLL_STDCALL, "FindWindowExA",nCalcHwnd, 0,"Edit","")
       lRunning  := ( DllExecuteCall( IsWindow, nEdithwnd ) != 0 )
//       msgbox(str(nCalchwnd)+"|"+str(nedithwnd))
    endif
enddo


msgbox( cPrevious, cResult, "Rechenergebnis" )

return
Gruß
Klaus
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12947
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 20 Mal
Danksagung erhalten: 51 Mal

Re: Windows Rechner (Calc)

Beitrag von AUGE_OHR »

Koverhage hat geschrieben:

Code: Alles auswählen

   IF ShellExecute(NIL, SHELL_OPEN, cProgPath,,,SW_SHOW)
also in der Zeile ist NIL verkehrt. es müsste (,SHELL_OPEN ...) sein ?!

Code: Alles auswählen

      lSuccess := DllCall( "SHELL32.DLL"  , DLL_STDCALL, ;
               "ShellExecuteA", AppDesktop():GetHWND(), "open", cPath+cFile,;
               NIL, CurDir(), SW_NORMAL )  // SW_MAXIMIZE

      DO CASE

      CASE lSuccess > 32                  // Aufruf erfolgreich
         Retvar := .T.

      Case lSuccess = SE_ERR_NOASSOC      // Keine verknpfte Anwendung

         // Falls ShowOpenWithDialog = True, wird der Dialog
         // "™ffnen mit" fr diese Datei angezeigt:
         // Shell "RunDLL32 shell32.dll,OpenAs_RunDLL " & Filename

         DllCall( "SHELL32.DLL"  , DLL_STDCALL, ;
               "OpenAs_RunDLL", AppDesktop():GetHWND(), NIL, cPath+cFile,;
               NIL, CurDir(), SW_NORMAL )  // SW_MAXIMIZE

         //  Die Auswahlm”glichkeit wird als Erfolg gewertet:
         Retvar := .T.
      OTHERWISE
         // ShellExecute war erfolglos.
         // Boolean-Standardwert False zurckgeben

         Retvar := .F.
      ENDCASE
warum nicht einfach

Code: Alles auswählen

   IF .NOT. nCalcHwnd > 0
      RunShell( "","CALC.EXE", .T.)
      RETURN
   ENDIF
Nachtrag : auch mit einem NIL funktioniert deine ShellExecute() nicht ... es gibt bei CALC.EXE kein SHELL_OPEN = "open" [-X

Die ShellExecuteA kann nur bei "Verknüpfung" wirken, also wenn du ein BMP hast dann Paint "open", aber CALC hat kein "open" ...

p.s. der "Rest" (WM_GETTEXT) funktioniert übrigens
gruss by OHR
Jimmy
Benutzeravatar
Koverhage
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2479
Registriert: Fr, 23. Dez 2005 8:00
Wohnort: Aalen
Hat sich bedankt: 110 Mal
Danksagung erhalten: 3 Mal
Kontaktdaten:

Re: Windows Rechner (Calc)

Beitrag von Koverhage »

Jimmy,

mit Shellexecute wird Calc auf beiden rechnern ausgeführt. Auf dem XP-Rechner bekommen
ich auch einen nCalcHwnd zurück, unter Windows 7 64-bit aber nicht.
Werde das mal mit Runshell probieren.
Gruß
Klaus
Benutzeravatar
Koverhage
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2479
Registriert: Fr, 23. Dez 2005 8:00
Wohnort: Aalen
Hat sich bedankt: 110 Mal
Danksagung erhalten: 3 Mal
Kontaktdaten:

Re: Windows Rechner (Calc)

Beitrag von Koverhage »

Auch mit RunShell läuft es unter Windows 7 64-bit nicht (bei mir)
Unter Windows XP läuft alles TOP.
Gruß
Klaus
Benutzeravatar
urbi
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 142
Registriert: So, 26. Mär 2006 18:47
Wohnort: 76185 Karlsruhe
Kontaktdaten:

Re: Windows Rechner (Calc)

Beitrag von urbi »

Hi,

habe vor langer Zeit mal einen Rechner geschrieben,

beim Aufruf einfach das sleobject übergeben:

z.B. ::PBEDITCLC:ACTIVATE:={||RECHNER(editfocus,0),SETAPPFOCUS(editFocus)}

mit F10 wird das Ergenis an das sleobject übergeben und der Rechner geschossen.

Bild

wenn interessiert kann ich gerne das Prgfile zur Verfühgung stellen

Gruss Urbai
urbi
Benutzeravatar
Herbert
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 1991
Registriert: Do, 14. Aug 2008 0:22
Wohnort: Gmunden am Traunsee, Österreich
Danksagung erhalten: 3 Mal
Kontaktdaten:

Re: Windows Rechner (Calc)

Beitrag von Herbert »

Ich habe auch einen ganz einfachen Rechner geschrieben. Als Idee zum Verbessern.
'!' setzt die im SLE sichtbare Zahl in die Zwischenablage.
Dateianhänge
Rechner
Rechner
calchs.jpg (17.72 KiB) 14690 mal betrachtet
Grüsse Herbert
Immer in Bewegung...
Benutzeravatar
Koverhage
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2479
Registriert: Fr, 23. Dez 2005 8:00
Wohnort: Aalen
Hat sich bedankt: 110 Mal
Danksagung erhalten: 3 Mal
Kontaktdaten:

Re: Windows Rechner (Calc)

Beitrag von Koverhage »

Da der Aufruf von Calc unter beiden System funktioniert, lasse ich das jetzt so.
Wenn der Anwender ein System hat, wo die Rückgabe nicht funktioniert
ist ja einfach in Calc auf Bearbeiten zu gehen und kopieren zu sagen
und das Ergebnis mit strg+v einzufügen.
Gruß
Klaus
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12947
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 20 Mal
Danksagung erhalten: 51 Mal

Re: Windows Rechner (Calc)

Beitrag von AUGE_OHR »

@Urbi und @Herbert

danke für euren Vorschlag.
ich sehe in diesem Thread weniger den "Rechner" denn auf diese Art und Weise kann ich ja "alles mögliche" damit machen z.b. einen Text aus Notepad holen/setzen.

alle "normalen" Fenster finde ich ja auch in dem Taskmanager, nun suche ich den Weg für die Programm welche sich im Sys_Tray abgelegt haben.

Da ist z.b. "Fritz" welcher mir ja auch die Rufnummer im A/B anzeigt ...
mittels WinID http://www.dennisbabkin.com bekomme ich ja das Handle und Parent ClassName raus.
ich muss es nun "auf-poppen" und mir dann das Control suchen welches ich "auslesen" möchte.

Frage : was bedeutet Parent ClassName "#32770"
gruss by OHR
Jimmy
Benutzeravatar
Herbert
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 1991
Registriert: Do, 14. Aug 2008 0:22
Wohnort: Gmunden am Traunsee, Österreich
Danksagung erhalten: 3 Mal
Kontaktdaten:

Re: Windows Rechner (Calc)

Beitrag von Herbert »

Noch ein Nachtrag:
Läuft doch unter Win7 64bit
Koverhage hat geschrieben:Jimmy,
mit Shellexecute wird Calc auf beiden rechnern ausgeführt. Auf dem XP-Rechner bekommen
ich auch einen nCalcHwnd zurück, unter Windows 7 64-bit aber nicht.
Werde das mal mit Runshell probieren.

Code: Alles auswählen

        RunDefaultShellProg(0,"open",'Calc.exe',,,SW_SHOWNORMAL)

FUNCTION RunDefaultShellProg(Hwnd,cVerb,cFile,cParam,cDir,nShow)
Local  cExe := space(256)
LOCAL nPos, nRet
nPos := rat("\", cFile)
IF nPos > 0
  cDir := substr(cFile, 1, nPos)
  cFile := substr(cFile, nPos+1)
ENDIF
nRet := FindExecutableA(cFile, cDir, @cExe)
IF nRet > 32
   nRet := ShellExecuteA(Hwnd,cVerb,cFile,cParam,cDir,nShow)
ENDIF
RETURN nRet
Grüsse Herbert
Immer in Bewegung...
Alfred_10
Rookie
Rookie
Beiträge: 8
Registriert: Di, 19. Aug 2014 13:57
Danksagung erhalten: 1 Mal

Re: Windows Rechner (Calc)

Beitrag von Alfred_10 »

Moin zusammen.

Kann mir jemand helfen oder hat vielleicht eine fertige Lösung um den Windows Rechner in eine xBase++ App zu integrieren?
Bekomme es nicht zum laufen.

nCalcHwnd := DllCall("User32.dll",DLL_STDCALL,"FindWindowA",0,"Rechner"+Chr(0) )
Funktioniert, hier kommt das Handle zurück. Rechner ist gestartet.

local nCalcHwnd := DllCall("User32.dll",DLL_STDCALL, "FindWindowExA", 0, 0, "SciCalc", "Rechner")
Hier kommt immer nur 0 zurück

local nEdithwnd := DllCall("User32.dll",DLL_STDCALL, "FindWindowExA",nCalcHwnd, 0,"Edit","")
Demzufolge kommt hier auch 0 zurück

Ich teste auf Win 11 Pro.

Grüsse, Alfred
Antworten

Zurück zu „Windows, API“