Newsgroup: it.comp.lang.delphi
Titolo: Esportazione mancante in Win95

Ciao ragazzi.
Riguardo al mio vecchio post nel quale chiedevo come settare la stampante di
default sotto Win2000 senza toccare i registry, dissi di aver trovato la
soluzione modificando la winspool (inserendo le esportazioni alle nuove DLL
SetDefaultPrinter e GetDefaultPrinter), rinominandola e inserendola nella
cartella del mio progetto.
Ora, sotto win2000 tutto ok, ma nelle macchine con Win95 all'avvio
dell'applicazione il programma dà errore dicendo che è collegato ad una
esportazione mancante in winSpool.DRV (appunto la setdefaultprinter).
Esiste il modo di ovviare a questo inconveniente?
Grazie, CIAOUX!!

 Esiste il modo di ovviare a questo inconveniente?
Non credo che esista, poichè la documentazione Microsoft parla chiaramente
di funzione utilizzabile solo nei sistemi basati su Kernel NT.
Ti riporto, direttamente dalla pagina di msdn:

 Esiste il modo di ovviare a questo inconveniente?
Non credo che esista, poichè la documentazione Microsoft parla chiaramente
di funzione utilizzabile solo nei sistemi basati su Kernel NT.
Ti riporto, direttamente dalla pagina di msdn:
Requirments:
  Windows NT/2000/XP: Included in Windows 2000 and later.
  Windows 95/98/Me: Unsupported.
Il mio "non credo" è dato dal fatto che ho visto "porting" non ufficiali
verso sistemi 9x di funzioni presenti su piattaforme NT (eg.
CreateRemoteThread()).
Tuttavia mi fiderei poco di queste "strade alternative".
Ciao
--
- Carlo -

Ciao Carlo!
Sě, ho visto la pagina di documentazione di MSDN, dove dice che la
SetDefaultPrinter č una funzione introdotta in Win2k e successivi....
ma.... io nel codice discrimino se sono sotto Kernel NT o 9x e uso funzioni
diverse per settare la stampante di default; con l'ultima modifica ho solo
modificato la funzione per gestire il caso NT, e l'errore non avviene al
momento della chiamata a SetDefaultPrinter ma proprio all'avvio dell'app.
Ora, io avevo anche provato questo, ma senza risultati.... (ovviamente)
uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ExtCtrls, Buttons, printers, registry, IniFiles, Grids, DBGrids,
  ComCtrls, proc,{$ifNdef Win95} dmWinSpool,{$endif} Variants;
<<<--------
.
.
.
.
function TUScelta31.Setta_Stampante_NT(PrinterName: string): Boolean;
begin
   {$ifNdef Win95}
      if SetDefaultPrinter(PChar(PrinterName)) then
         Result := True
      else
         Result := False;
   {$endif}
end;
cioč, il punto č : io  non posso neanche "nominare" tale funzione senza
usarla se il pgm gira anche sotto Win95?

 Ora, io avevo anche provato questo, ma senza risultati.... (ovviamente)
mmm ... strano!
Prova a seguire la strada che ho usato io (Win32Platform) per discriminare
tra Windows NT  e Windows 9x su Process Inspector.
Te ne riporto un pezzo sperando che possa esserti utile:
{ Lista di moduli per Win9x - Privata}
function W9x_ModuleList(var ModuleInfoArray: TModInfoArr; ProcessID: dWord):
boolean;
var hSnapShot: THandle;
    isNotLast: Boolean;
    ModuleEntry: TModuleEntry32;
    Indice: Integer;
begin
  Result := false;
  hSnapShot:=CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, ProcessID);
  If (hSnapShot<>-1) then
  begin
    Indice := 1;
    Result := True;
    SetLength(ModuleInfoArray,Indice);
    IsNotLast:=Module32First(hSnapShot,ModuleEntry);
    While IsNotlast do
    begin
      ModuleInfoArray[Indice-1] := ExtractModuleData(ModuleEntry);
      IsNotLast:=Module32Next(hSnapShot,ModuleEntry);
      Inc(Indice);
      SetLength(ModuleInfoArray,Indice);
    end;
    SetLength(ModuleInfoArray,Indice-1);
  end;
  CloseHandle(hSnapShot);
end;
{ Lista di moduli per WinNT - Privata }
function WNT_ModuleList(var ModuleInfoArray: TModInfoArr; ProcessID: dWord):
boolean;
var hProcess: THandle;
    hModule: Array [1..1024] of THandle;
    cbReturned: dWord;
    mName: pChar;
    mInfo: TModuleInfo;
    Indice, Count: Integer;
begin
 Result := False;
 hProcess := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ,
                         false,ProcessID);
 if (hProcess <> 0) then begin
    Result := True;
    EnumProcessModules( hProcess, @hModule, sizeof(hModule), cbReturned );
    mName := AllocMem(MAX_PATH);
    Count := cbReturned div SizeOf(THandle);
    for Indice := 1 to Count do begin
        GetModuleBaseName(hProcess,hModule[Indice],mName,MAX_PATH);
        GetModuleInformation(hProcess,hModule[Indice],@mINFO,SizeOf(mInfo));
        SetLength(ModuleInfoArray,Indice);
        ModuleInfoArray[Indice-1].ModInstance := hModule[Indice];
        ModuleInfoArray[Indice-1].ModuleSize  := mInfo.SizeOfImage;
        ModuleInfoArray[Indice-1].ModuleName  := mName;
    end;
    FreeMem(mName);
 end;
 CloseHandle(hProcess);
end;
{ Funzione pubblica per la lista dei moduli }
function ModuleList(var ModuleInfoArray: TModInfoArr; ProcessID: dWord):
boolean;
Begin
  result := false;
  if Win32Platform = VER_PLATFORM_WIN32_WINDOWS then
     Result := W9x_ModuleList(ModuleInfoArray,ProcessID) else
  if Win32Platform = VER_PLATFORM_WIN32_NT then
     Result := WNT_ModuleList(ModuleInfoArray,ProcessID);
end;
Ovviamente fammi sapere! Ciao!
--
- Carlo -

Eccolo.
Ho provato.
Ma ovviamente la riga di codice
   if Win32Platform = VER_PLATFORM_WIN32_NT then
la posso utilizzare solo nell'implementazione della funzione e non nelle
uses, come ho provato a fare prima
Il problema continua all'avvio del programma :((
umf

 ha scritto nel messaggio
news:b85lr7$e0r$1...@newsreader.mailgate.org...

Hai collegato in modo statico dentro al codice una procedura esportata da
qualche dll (nel caso in questione setdefaultprinter)?
In questo caso credo che la soluzioni sia quella di collegarla a runtime
solamente se l'ambiente è quello giusto
Ciao
Matteo

Centro!
Hai qualche esempio?

 Hai qualche esempio?
mmm
credo che ci si possa basare su queste funzioni:
loadlibrary per mappare nello spazio del processo una dll
getprocaddress per avere un puntatore alla procedura esportata dalla DLL
Se la versione del SO è NT, mappi la dll, altrimenti fai come quelli di
faenza (che fanno senza ^__^) o trovi soluzioni alternative senza l'uso di
quella DLL...
Ciao
Matteo

Capito.
No, DEVO usare quella funzione in quella dll purtroppo. E' l'ultima
spiaggia, viste le condizioni in cui dovrò operare.
Grazie mille ancora.
CIAOUX!

 getprocaddress per avere un puntatore alla procedura esportata dalla DLL
Credi bene. L'esempio lo ho scritto io:
var hDLL: THandle;
    funcPointer: TFarProc;
    SetDefaultPrinter: TSetDefaultPrinter;
    OsRelease: TOsVersionInfo;
begin
   OsRelease.dwOSVersionInfoSize := SizeOf(TosVersionInfo);
   GetVersionEx(OsRelease);
   if (OsRelease.dwPlatformId = VER_PLATFORM_WIN32_NT) and
      (OsRelease.dwMajorVersion > 4) then
       begin
           hDLL := LoadLibrary('winspool.drv');
           if (hDLL < 0) then
               RaiseLastWin32Error()
           else begin
               try
                   funcPointer := GetProcAddress(hDLL,
'SetDefaultPrinterA');
                   if funcPointer <> nil then begin
                       SetDefaultPrinter := TSetDefaultPrinter(funcPointer);
                   end else
                       ShowMessage('Impossibile linkare dinamicamente la
funzione');
                   if not SetDefaultPrinter('NomeStampante') then
                       RaiseLastWin32Error();
               finally
                   FreeLibrary(hDLL);
               end;
           end;
       end;
end;
Ciao! ;-)
--
- Carlo -