(DELPHI) Odczyt zainstalowanej pamieci RAM - Problem

0

Witam.
Postaram sie szybko i na temat.
Mam o to procedure

procedure TForm1.ReadRAM;
var
  Memory : TMemoryStatus;
begin
  Memory.dwLength:=SizeOf(Memory);
  GlobalmemoryStatus(Memory);
  sLabel10.Caption := (FloatToStr(Memory.dwTotalPhys / 1024) + ' kB calkowitej pamieci');
end;

Dziala ona prawidlowo lecz nie moge/nie wiem jak zamienic to z KB na MB/GB..
Chce by przy starcie programu zostala dodana informacja do Labela.
np.
Pamiec RAM: 1GB, a nie 1024Mb lub 1048048Kb..

Wiecie jak to osiagnac? Taka konwersje lub innym sposobem lub kodem?
Z gory dzieki za odpowiedz.
Pozdrawiam.

0

No ale w czym problem? 1MB = 1024KB, 1GB = 1024MB

0

jak az tak bardzo nie chce Ci sie myslec to mozesz uzyc gotowej funkcji zamieniajacej ilosc bajtow na odpowiednia jednostke.
chociaz nie wiem dokladnie jakie wartosci bedzie podawac, ta funkcja jest stosowana w windowsie do wyswietlania rozmiarow plikow.

  function StrFormatByteSize(dw: DWORD; szBuf: PChar; uiBufSize: UINT):
           PChar; stdcall; external 'shlwapi.dll' name 'StrFormatByteSizeA';
  function StrFormatKBSize(qdw: LONGLONG; szBuf: PChar; uiBufSize: UINT):
           PChar; stdcall; external 'shlwapi.dll' name 'StrFormatKBSizeA';

function SizeToStr(size:DWORD):string;
var arrSize: array[0..255] of Char;
begin
  StrFormatByteSize(size, arrSize, Length(arrSize)-1);
  result:=Trim(arrSize);
end;

a tak poza tym to faktycznie nie wiem z czym Ty masz problem.
jesli pamieci jest mniej niz 1gb to wyswietlasz w mb. jesli wiecej to w gb.

0

tak masz racje jak jest wiecej niz 1 gb to ma sie wyswietlic w GB a jak mniej to w MB, a problem moj polega na tym ze wszystko mi pokazuje w KB... :( juz dlugo nie pracowalem w delphi i sa tego skutki.. :/

ta fuckcja co dales przyda sie wiec?
bo jak pisalem wyzej mam cos do odczytu pamieci.. tyle ze odczytuje to w KB...
twoja to zamieni ?

0

no to jak masz w kb to podziel przez 1024 i dostaniesz w mb. jesli mb bedzie >=1024 to podziel jeszcze raz przez 1024 i wtedy bedziesz mial w gb.

0

juz o tym myslalem ale dlugie liczby i tak wychodza.
ale ok zaraz bede dzialal, jak mi sie wszystko powiedzie to sie z tym tu podziele :)
Dzieki za pomoc

Edit1.
No to problem, mam u siebie 1 GB w PC. W moim programie pokazuje mi 1048048 KB.
Gdy podzielilem..1048048 KB na 1024 dostalem 1023,484375 MB gdy zrobie to jeszcze raz dostaje 0,999496459960938 GB czyli ze 1 GB.
Program caly czas pokazuje mi kilkadziesiat liczb, i nie zmienia sam jednostek z KB na MB, lub GB.
Wiem... by zmienil musze cos napisac, ale nie mam pomyslu co, a o kod wstyd pytac, na google probowalem..
Nie chce by bylo jak w Menadrzeze zadan, tylko jak wejdziesz we wlasciwosci komputera.
Zeby samo wykrylo czy ma byc MB czy GB a jak nie pelne to zeby dodalo np. jak wyzej dalo mi wartosc 0.9...GB by dodalo do 1GB)
Nie wiem jak to powiedziec inaczej.
Mam nadzieje ze pomozesz mi z tym, bo jak nie to forum to sobie juz nie poradze..
Dzieki.

0
  if Memory.dwTotalPhys >= 1024*1024*1024 then
    sLabel10.Caption := IntToStr(Round(Memory.dwTotalPhys/1024/1024/1024)) + ' G' else
  if Memory.dwTotalPhys >= 1024*1024 then
    sLabel10.Caption := IntToStr(Round(Memory.dwTotalPhys/1024/1024)) + ' M' else
  if Memory.dwTotalPhys >= 1024 then
    sLabel10.Caption := IntToStr(Round(Memory.dwTotalPhys/1024)) + ' K' else
    sLabel10.Caption := IntToStr(Memory.dwTotalPhys) + ' ';
  sLabel10.Caption:=sLabel10.Caption+'B calkowitej pamieci' 
0

Wlasnie próbowałem zrobic cos takiego i wyszlo mi: (No dziala, ale tylko podemnie bo mam 1 GB)

procedure TForm1.ReadRAM;
var
  Memory : TMemoryStatus;
  RAM : String;
begin
Memory.dwLength:=SizeOf(Memory);
  GlobalmemoryStatus(Memory);
  RAM:= (FloatToStr(Memory.dwTotalPhys / 1024 / 1024 / 1024) + ' kB ca³kowitej pamiêci');
  if (RAM >= '0,8') and (RAM <= '0,9999') then
  RAM:= '1 GB';
  sLabel10.Caption := RAM;
end;

A co twojego kodu to sprawdzilem i prawie dziala, zrobiles wiecej, szybciej i lepiej ode mnie.
Pisze tylko 1023 MB Calkowitej pamieci, a nie 1 GB :P Wiec jakas cyferke bedzie trzeba chyba zmienic.

Dzieki ze poswieciles troszke czasu.

0

w zasadzie to zawsze pamieci maja podana zblizona pojemnosc.
1gb to wlasnie bedzie 1023mb.
40gb dysk zawsze bedzie troche mniejszy itd...

0
djkolo napisał(a)

Pisze tylko 1023 MB Calkowitej pamieci, a nie 1 GB

Zgadza się.
Przecież 1048048 KB / 1024 = 1023,484375 MB a po zaokrągleniu = 1023 MB

Sprawdź dokładną wartość w bajtach i przelicz ręcznie.

sLabel10.Caption:=IntToStr(Memory.dwTotalPhys)+' B calkowitej pamieci'
0

tak zgadza sie, ale nie damy rady jakos tego zaokraglic do 1 GB ? rozumiem o co Ci chodzi :) no kodzik perfekt ale lepiej wyglada jak jest 1 GB - tak samo windows robi w właściwościach systemu i wyglada ladnie :)
Jezeli nie masz pomyslu to zrozumie i dzieki za pomoc, ale fajnie bylo by to zmienic :)

0

moze zaloz, ze najmniejsza kosc pamieci to 16mb i wymus otrzymanie wielokrotnosci tej liczby.
chociazz... przy wiekszej ilosci ramu, odchylenie moze byc wieksze niz 16mb i wtedy znow pojawia sie przecinki.
hmm.. mi winxp pokazuje "0,99 GB RAM" :D

0

http://en.wikipedia.org/wiki/Serial_presence_detect

Zawsze możesz odczytać fizyczną ilość pamięci używając tego powyżej. Kwestia znalezienia gotowego rozwiązania na pobranie tych wartości (jeżeli nie ma gotowej biblioteki to może być to dość trudne).

edit: aha - przeszukaj jeszcze WMI, prawdopodobnie system sam parsuje te informacje z BIOSu i tam umieszcza.

jeszcze jeden edit: faktycznie istnieje klasa w WMI, "Win32_PhysicalMemory", właściwość Capacity zawiera pojemność pamięci w bajtach, dokładnie. 2147483648 u mnie, czyli dokładnie 2GB. Wystarczy zsumować wszystkie kości i będziesz miał swoją dokładną wartość.

0
function FormatByteSize(const Rozmiar: Int64): string;
const
 KB = 1024;      //kilobyte
 MB = 1024 * KB; //megabyte
 GB = 1024 * MB; //gigabyte
begin
 if Rozmiar < KB then Result := IntToStr(Rozmiar) + ' bajtów'
 else
 if Rozmiar < MB then Result := FormatFloat('#.## kB', Rozmiar / KB)
 else
 if Rozmiar < GB then Result := FormatFloat('#.## MB', Rozmiar / MB)
 else Result := FormatFloat('#.## GB', Rozmiar / GB);
end;

procedure TForm1.ReadRAM;
var
  Memory : TMemoryStatus;
begin
  Memory.dwLength:=SizeOf(Memory);
  GlobalmemoryStatus(Memory);
  sLabel10.Caption := FormatByteSize(Memory.dwTotalPhys);
end;

Funkcję 'FormatByteSize' można jeszcze zoptymalizować - ucinając sprawdzanie "bajtów" i "kB".

0

Ale jaki sens zaokrąglać i zakłamywać wynik? Jak wychodzi 0,99 GB zamiast pełnego 1 GB to tyle jest, i tak trzeba wyświetlać.

0

nom, ale nie pokazuje 0,9 GB czy 0,99 Gb.. tylko 1023 MB a to smiesznie wyglada..
jakby pokazywalo juz te 0,99 czy 0,9 to bylo by tez dobrze :)

0

Załóżmy zatem, że obecne komputery mają pamięć o wielkości rzędu GB.
Możemy wyświetlić w GB z dokładnością do 2 miejsc po przecinku.

  sLabel10.Caption:=Format('%.2f GB',[Memory.dwTotalPhys/1024/1024/1024]);

Ale uważam że rozwiązanie które podałem wyżej jest lepsze.

0

Okej, wielkie dzieki za pomoc, najwazniejsze ze juz mam to co chcialem.
Po piwku dla wszystkich (+18) :D
Pozdrawiam.

1 użytkowników online, w tym zalogowanych: 0, gości: 1