Ścieżka do folderu specjalnego - desktop

Ścieżka do folderu specjalnego - desktop
K9
  • Rejestracja:około 12 lat
  • Ostatnio:ponad 4 lata
  • Postów:14
0

Witam
Mam problem z pewnym zagadnieniem. Chcę stworzyć na pulpicie folder. Używam procedury

Kopiuj
mkdir((GetSpecialFolderPath(CSIDL_DESKTOPDIRECTORY))+'\Test');

Teoretycznie działa. Jednak problem się pojawia, gdy zmienię profil w Windowsie, który posiada polskie litery np. profil o nazwie Paweł, pojawia się błąd i nie tworzy folderu - polskie znaki zamieniają się w ?. Próbowałem używać AnsitoUTF8 i UTF8toAnsii ale nie pomogło.

Proszę o pomoc. Z góry dziękuje

edytowany 2x, ostatnio: flowCRANE
flowCRANE
Moderator Delphi/Pascal
  • Rejestracja:ponad 13 lat
  • Ostatnio:około 6 godzin
  • Lokalizacja:Tuchów
  • Postów:12175
2

Funkcja SHGetSpecialFolderPath jest przestarzała i w niedalekiej przyszłości zostanie całkowicie usunięta z WinAPI. Dla wsparcia systemów starszych niż Vista wykorzystaj SHGetFolderPath, a dla nowszych użyj SHGetKnownFolderPath.

Po drugie, używaj funkcji z sufiksem W, czyli wersji wspierającej unikod.


Pracuję nad własną, arcade'ową, docelowo komercyjną grą z gatunku action/adventure w stylu retro (pixel art), programując silnik i powłokę gry od zupełnych podstaw, przy użyciu Free Pascala i SDL3. Więcej informacji znajdziesz na moim mikroblogu.
edytowany 1x, ostatnio: flowCRANE
K9
  • Rejestracja:około 12 lat
  • Ostatnio:ponad 4 lata
  • Postów:14
0

Witam po dłuższej przerwie

dziękuję za podpowiedź

Idąc tym tropem znalazłem kolejny problem (zaczerpnąłem przykład z Internetu)

Kopiuj
uses 
...
type
...
const
FOLDERID_DESKTOP: TGUID = '{B4BFCC3A-DB2C-424C-B029-7FE99A87C641}';
KF_FLAG_CREATE = $00008000;

function SHGetKnownFolderPath(const rfid: TGUID; dwFlags: DWord; hToken: THandle; var ppszPath: LPWSTR): HResult; stdcall; external 'Shell32.dll';

....

procedure TForm5.SpeedButton14Click(Sender: TObject);
begin

showmessage(SHGetKnownFolderPath(FOLDERID_DESKTOP, KF_FLAG_CREATE, 'test', Path));   

Pojawia mi się błąd podczas kompilacji z uwagi na "LPWSTR", nie wiem jak sobie z nim poradzić

Dziękuję z góry za pomoc

edytowany 1x, ostatnio: flowCRANE
Tasmanian Devil
Hej! Twój post prawdopodobnie zawiera niesformatowany kod. Użyj znaczników ``` aby oznaczyć, co jest kodem, będzie łatwiej czytać. (jestem botem, ta akcja została wykonana automatycznie, prawdopodobieństwo 0.9994231)
flowCRANE
Moderator Delphi/Pascal
  • Rejestracja:ponad 13 lat
  • Ostatnio:około 6 godzin
  • Lokalizacja:Tuchów
  • Postów:12175
0
koper9090 napisał(a):

Pojawia mi się błąd podczas kompilacji z uwagi na "LPWSTR", nie wiem jak sobie z nim poradzić

Wklej dokładny komunikat błędu, jeśli chcesz szybko uzyskać pomoc.


Pracuję nad własną, arcade'ową, docelowo komercyjną grą z gatunku action/adventure w stylu retro (pixel art), programując silnik i powłokę gry od zupełnych podstaw, przy użyciu Free Pascala i SDL3. Więcej informacji znajdziesz na moim mikroblogu.
Mariusz Bruniewski
Mariusz Bruniewski
  • Rejestracja:prawie 20 lat
  • Ostatnio:ponad 3 lata
  • Lokalizacja:Świecie
0

Proponuję utworzyć folder z uprawnieniami administratora. Możesz mieć kod, który działa poprawnie a stanie się dla Ciebie łamigłówką. tylko z pozycji uprawnień. kod działa w delphi i lazarusie.

Kopiuj
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ShlObj, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}


function FolderDesktop(const Folder: Integer): string;
var
  Path: shortstring;
begin
  SHGetSpecialFolderPath(0, @Path, Folder , False);
  FolderDesktop := StrPas(@Path);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  Sciezka: string;
  s : string;
begin
  s := InputBox('Podaj nazwę folderu', 'Podaj proszę nazwę folderu utworzonego w Pulpit', s);
  Sciezka :=  FolderDesktop(CSIDL_DESKTOP);

  Caption := 'Ścieżka zostanie utworzona'+Sciezka;

  CreateDir(Sciezka+'\'+s);  //  Nowy folder o nazwie wpisanej do inputbox
end;

end.


Umysł pozytywny szuka sposobów, jak coś wykonać; umysł negatywny wyszukuje sposoby, by uzasadnić, że czegoś nie można zrobić.
~~ Napoleon Hill ~~
edytowany 2x, ostatnio: Mariusz Bruniewski
Mariusz Bruniewski
Mariusz Bruniewski
  • Rejestracja:prawie 20 lat
  • Ostatnio:ponad 3 lata
  • Lokalizacja:Świecie
0

Demo w Lazarus


Umysł pozytywny szuka sposobów, jak coś wykonać; umysł negatywny wyszukuje sposoby, by uzasadnić, że czegoś nie można zrobić.
~~ Napoleon Hill ~~
cerrato
Czyli jednak Lazarus wrócił do łask? :) I dobrze.
Mariusz Bruniewski
Mariusz Bruniewski
  • Rejestracja:prawie 20 lat
  • Ostatnio:ponad 3 lata
  • Lokalizacja:Świecie
1

W takim razie, kiedy masz do czynienia z polskimi znakami w ścieżce używaj nazwy DOS Np.

Kopiuj
begin
Showmessage('LOKALIZACJA PROGRAMU Project1.exe'+#13+
 'Ścieżka pełna : '+Application.ExeName+#13+
 'Ścieżka skrócona : '+ExtractShortPathName(application.ExeName) ;
end;

Ścieżka skrócona w tym przypadku właściwy wybór


Umysł pozytywny szuka sposobów, jak coś wykonać; umysł negatywny wyszukuje sposoby, by uzasadnić, że czegoś nie można zrobić.
~~ Napoleon Hill ~~
edytowany 1x, ostatnio: Mariusz Bruniewski
flowCRANE
Moderator Delphi/Pascal
  • Rejestracja:ponad 13 lat
  • Ostatnio:około 6 godzin
  • Lokalizacja:Tuchów
  • Postów:12175
1

Funkcja SHGetSpecialFolderPath jest przestarzała i nie warto jej w ogóle używać. To już nie chodzi o to, że jest zdeprecjonowana – została już oznaczona jako niewspierana, więc przy najbliższej okazji zostanie całkowicie usunięta z biblioteki systemowej. A to spowoduje, że programy ją wykorzystujące nie dość że nie będą działać prawidłowo, to mogą się w ogóle nie uruchomić, skoro nie znajdą punktu wejścia. Tak więc to co proponujesz nie ma najmniejszego sensu.

Jeśli zależy komuś na wsparciu systemów starszych niż Vista, należy skorzystać z funkcji SHGetFolderPath. Ta funkcja jest zdeprecjonowana, ale w najbliższych latach nie grozi jej usunięcie z API. Dla systemów Vista+ jest funkcja SHGetKnownFolderPath, więc jeśli wsparcie starych systemów nie jest potrzebne, jej należy użyć.


Pracuję nad własną, arcade'ową, docelowo komercyjną grą z gatunku action/adventure w stylu retro (pixel art), programując silnik i powłokę gry od zupełnych podstaw, przy użyciu Free Pascala i SDL3. Więcej informacji znajdziesz na moim mikroblogu.
Azarien
przy najbliższej okazji zostanie całkowicie usunięta z biblioteki systemowej - mocno wątpliwe, Microsoft nie usuwa API na prawo i lewo, bo kompatybilność wsteczna się dla nich liczy.
flowCRANE
Tak, ale nie w nieskończoność. Tym bardziej, że faza bycia deprecated trwała lata i już dawno minęła.
K9
  • Rejestracja:około 12 lat
  • Ostatnio:ponad 4 lata
  • Postów:14
0

Witam jeszcze raz.
korzystałem z różnych podpowiedzi jednak żadna nie przyniosła rozwiązania problemu związanego z stworzeniem folderu na pulpicie. Wszystko niby działa do czasu konta w Windows z polskimi znakami. Za każdym razem występuje komunikat "Nie wykonano procedury gdyż nie znaleziono \Pawe?\Deskop\Test"

Kopiuj
np.
uses
...shlobj...

const
  FOLDERID_DESKTOP: TGUID = '{B4BFCC3A-DB2C-424C-B029-7FE99A87C641}';
  KF_FLAG_CREATE = $00008000;

  function SHGetKnownFolderPath(const rfid: TGUID; dwFlags: DWord; hToken: THandle; var ppszPath: LPWSTR): HResult; stdcall; external 'Shell32.dll';
        

podczas kompilacji wyskakuje błąd

Kopiuj
unit5.pas(406,1) Error: Identifier not found "LPWSTR"

Czy mógłbym prosić o jakąś podpowiedź co robię źle?

edytowany 1x, ostatnio: flowCRANE
PD
  • Rejestracja:ponad 22 lata
  • Ostatnio:około 14 godzin
3
Kopiuj
uses
  WinDirs, LazUTF8, LazFileUtils;

begin
  CreateDirUTF8(WinCPToUTF8(GetWindowsSpecialDir(CSIDL_DESKTOPDIRECTORY)) + 'test');
end;

pozdrawiam
paweld
flowCRANE
Moderator Delphi/Pascal
  • Rejestracja:ponad 13 lat
  • Ostatnio:około 6 godzin
  • Lokalizacja:Tuchów
  • Postów:12175
1
koper9090 napisał(a):

podczas kompilacji wyskakuje błąd

Kopiuj
unit5.pas(406,1) Error: Identifier not found "LPWSTR"

Czy mógłbym prosić o jakąś podpowiedź co robię źle?

Źle robisz, że nie próbujesz zrozumieć dlaczego ten błąd dostajesz. ;)

A powód jest prosty – typ danych LPWSTR nie jest znany w czasie kompilacji, więc musisz dodać moduł, który zawiera jego deklarację. Jest to typ danych przeznaczony dla funkcji WinAPI, więc jego deklaracja znajduje się w module Windows. Tak więc dodaj ten moduł do listy uses i próbuj.

Choć @Paweł Dmitruk podał jeszcze inne rozwiązanie, więc spróbuj też jego sugestii.


Pracuję nad własną, arcade'ową, docelowo komercyjną grą z gatunku action/adventure w stylu retro (pixel art), programując silnik i powłokę gry od zupełnych podstaw, przy użyciu Free Pascala i SDL3. Więcej informacji znajdziesz na moim mikroblogu.
edytowany 1x, ostatnio: flowCRANE
Azarien
  • Rejestracja:ponad 21 lat
  • Ostatnio:około 3 godziny
2
furious programming napisał(a):

Po drugie, używaj funkcji z sufiksem W, czyli wersji wspierającej unikod.

Jest też nowe rozwiązanie - począwszy od Windows 10 ver 1903 można z odpowiednim manifestem w exeku używać UTF-8 w funkcjach z sufixem A:

https://docs.microsoft.com/en-us/windows/uwp/design/globalizing/use-utf8-code-page

K9
  • Rejestracja:około 12 lat
  • Ostatnio:ponad 4 lata
  • Postów:14
0

Dziękuje za szybka odpowiedź, sprawę rozwiązanie @PAWEŁ Dmitruk.

Co do modułu Windows to mogę nadmienić, że po jego wpisaniu pojawił mi się kolejny błąd przy istniejących procedurach w kodzie źródłowym

np

Kopiuj
procedure TForm5.ListBox7MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);    

...
ItemAtPos(Point(X,Y),true);
Kopiuj
unit5.pas(1201,34) Fatal: Syntax error, ")" expected but "," found

błąd dotyczy przecinka pomiędzy X Y

bez tego modułu działa poprawnie, z modułem niestety nie

edytowany 2x, ostatnio: flowCRANE
Tasmanian Devil
Hej! Twój post prawdopodobnie zawiera niesformatowany kod. Użyj znaczników ``` aby oznaczyć, co jest kodem, będzie łatwiej czytać. (jestem botem, ta akcja została wykonana automatycznie, prawdopodobieństwo 0.99799985)
PD
  • Rejestracja:ponad 22 lata
  • Ostatnio:około 14 godzin
1
Kopiuj
ItemAtPos(Classes.Point(X, Y), True);

pozdrawiam
paweld
flowCRANE
Nie spodziewałem się, że moduł Classes posiada funkcję Point – zawsze używałem tej z modułu Types. :/
flowCRANE
Moderator Delphi/Pascal
  • Rejestracja:ponad 13 lat
  • Ostatnio:około 6 godzin
  • Lokalizacja:Tuchów
  • Postów:12175
3
koper9090 napisał(a):

Co do modułu Windows to mogę nadmienić, że po jego wpisaniu pojawił mi się kolejny błąd przy istniejących procedurach w kodzie źródłowym

Znany problem – występuje ”kolizja” identyfikatorów i kompilator wybiera pierwszy znany. Widać w Twoim przypadku, typ POINT z modułu Windows znany jest wcześniej niż funkcja Point z modułu Types (lub Classes), dlatego ten jest brany pod uwagę. Zapis z nawiasami kompilator traktuje jako rzutowanie, w którym przecinek oczywiście nie jest dozwolony – rzutowanie jest jednoargumentowe (jako wartość lub wynik wyrażenia). Dlatego określenie pochodzenia identyfikatora (jak pokazał @Paweł Dmitruk wyżej) jest konieczne.

To samo będzie w przypadku typu Windows.RECT oraz funkcji Types.Rect. Dlatego zamiast używania funkcji, polecam wykorzystać konstruktory typów danych, np. TPoint.Create czy TRect.Create – ból głowy będzie mniejszy.


Pracuję nad własną, arcade'ową, docelowo komercyjną grą z gatunku action/adventure w stylu retro (pixel art), programując silnik i powłokę gry od zupełnych podstaw, przy użyciu Free Pascala i SDL3. Więcej informacji znajdziesz na moim mikroblogu.
edytowany 4x, ostatnio: flowCRANE
K9
  • Rejestracja:około 12 lat
  • Ostatnio:ponad 4 lata
  • Postów:14
0

Dziękuję za podpowiedź

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.