[WinApi] *String*, *STRING*, *string*, *char*, *text* itd.

0

Witajcie,

Z konieczności zacząłem właśnie zagłębiać się w "WinMobAPI", czyli WinApi dla Windows dla urządzeń przenośnych, bo jak już dowiedziałem się, co parafia (wersja systemu windows), to "inne" WinApi. Miałem do czynienia z conajmniej kilkoma językami programowania w swoim życiu, podobnie technologiami (włączając w to API), ale na razie stwierdzam, że WinApi z Microsoftu chyba jest najbardziej frustrujące. Po krótce:

  • mnóstwo niekonsekwencji
  • kompletna olewka dobrych praktyk programistycznych i totalny chaos (Microsoft Press wydaje mnóstwo książek, ale programiści z MS nie trzymają się swoich własnych porad; chyba już wiem dlaczego software Microsoftu ma tyle błędów - przy takim podejściu do programowania?)
  • dobre, ale generalnie słabsze (mniej wygodne) IDE Visual Studio w porównaniu do innych produktów dla innych języków na rynku, no i w moim VS 2005 to chyba nie ma opcji zmiany kolorów (???), co jest pierwszą rzeczą w każdym IDE, od której zaczynam :/
  • chaotyczne przekazywanie parametrów do funkcji systemowych

Nigdy się wnętrznościami Windows nie interesowałem, ale ewidentnie Windows nie jest dobrze zaprojektowanym systemem (od strony programistycznej). Widać, że to system, którego kod się ciągnie od lat 80-tych i rozumiem, że przedsiębiorca (MS) oszczędza jeśli tylko może, ale to oszczędności na krótką metę jak widać.

Jednak najbardziej irytuje mnie mnogość typów. Fakt, że jest to po części spowodowane specyfiką C/C++ (wskaźniki etc.), po części tym o czym pisałem powyżej, ale efekt jest taki, że charów i stringów mamy do wyboru do koloru.

Tyle, że wybierającym jest tu system Windows, a właściwie programiści WinApi, którzy najwyraźniej dla własnej wygody dyktują co i jak. Ale jak pisałem, nie mam wyjścia i muszę się tego uczyć, więc z mojej strony tutaj prośba do bardziej doświadczonych: czy może mi ktoś wskazać jakieś dobre źródło z opisowym wyjaśnieniem co i jak z tekstowymi typami w Windows (poza MSDN)? I jak co konwertować między sobą? Oczywiście tymi praktycznie wykorzystywanymi, bo ja mam programować, a nie uczyć się teorii.

Z góry wielkie dzięki i pozdrawiam!

0

Krotka odpowiedz na razie, ale nie mam teraz czasu, zeby sie rozpisywac. Zauwaz przede wszystkim, ze wszystkie typy w WinApi to typedef'y sprowadzajace sie do typow wbudowanych. Predzej czy pozniej gdzies jest jakis, np.

#ifdef UNICODE
typedef LPCTSTR wchar*;
#endif

Z dobrych praktyk, ktore pamietam, to:

  • stosowanie makro _T("tekst") dla magic_values - dziala jak "tekst" dla kodowania ANSII, dla UNICODE uzywa wchar*.

Oprocz tego w wiekszosci uzywa sie dwoch typow LPTSTR (long pointer string) i LPTCSTR (long pointer constant string), czyli odpowiednio:

#ifdef UNICODE
typedef LPTSTR wchar*;
typedef LPTCSTR const wchar*;
#else
typedef LPTSTR char*;
typedef LPTCSTR const char*;
#endif

To sa glowne powody, dla ktorych typy standardowe zastapione sa typedefami. Zgodze sie, ze mocno irytuje fakt takiej ilosci typow, ale po pewnym czasie zaczyna sie ich uzywac naturalnie. Glownie dlatego, ze kompilator ciagle przypomina, ze np. nie da sie skonwertowac const char* na char* ;)

0

Dzięki za odpowiedź!

To mi już nieco rozjaśnia w głowie. Ale może napiszę, na jakim "problemie" musiałem zmarnować sporo czasu, przeszukując sieć. Jak pisałem, dopiero zaczynam z WinApi, więc być może to zabrzmi zabawnie, ale przykład z książki wskazywał, że w strukturze definiującej fonty w Windows ostatni parametr to TCHAR. Natomiast Visual Studio pisze o WCHAR. Zdaje się to to samo? W każdym razie następująca linijka kodu:

lf.lfFaceName = TEXT("MS Sans Serif");

Powoduje następujący błąd przy komplikacji:

cannot convert from 'const wchar_t [14]' to 'WCHAR [32]'

Po dłuższym przeszukaniu sieci w końcu się poddałem i poszedłem na łatwiznę, używając funkcji wcscpy, która co prawda rozwiązuje problem, ale nadal nie do końca rozumiem tę kwestię.

0

A ja uważam że WinAPI jest ok. Na co dzień i tak nikt nie pisze aplikacji okienkowych w WinAPI. Są od tego inne biblioteki. Często trzeba użyć w swoim programie jakieś funkcji systemowej. I bardzo dobrze że jest to zwykła funkcja ponieważ system powinien dostarczać nam funkcji na nieco niższym poziomie niż pisana przez nas aplikacja. Jeżeli chodzi o mnogość typów danych to też bardzo dobrze bo są to typy systemu(?) a nie konkretnego języka programowania.

Jak chcesz to opakuj sobie całe WinAPI w klasy i będzie wszystko ok. Może kiedyś nadasz swoim bibliotekom jakąś nazwę, np .NET Framework :-) (co nie oznacza że .NET Framework to WinAPI obudowane w klasy)

0

Ale w czym problem, że to przypisanie nie jest poprawne? Przecież w C++ nie przypiszesz jednej tablicy do drugiej, jakby to były tablice intów to by było to samo...
TCHAR to w zależności od (nie)zdefiniowania makra UNICODE jest zdefiniowane jako char (nie zdefiniowano) lub wchar_t (zdefiniowano). Visual mówi że to WCHAR bo pewnie masz ustawione w opcjach projektu kodowanie na unikod, a IntelliSense lubi rozwijać makra.

0

Tak jak piszę, dopiero zaczynam z WinApi. Następujące przypisanie jest jednak (tylko u mnie?) ok:
wchar_t moj_napis[256]=TEXT ("Napis");
A więc jednak da się przypisać do tablicy.

Prawdę mówiąc, te wszystkie makra mogą przyprawić o zawrót głowy. Zamiast pisać program, muszę dochodzić co, jak i gdzie jest zdefiniowane. Może to tak tylko na początku jest w WinApi, bo prawdę mówiąc jednak nigdy nie lubiłem korzystać z makr - nigdzie - i właściwie obywałem się bez nich. Zamiast tego używam po prostu funkcji.

0
forsberg napisał(a)

Następujące przypisanie jest jednak (tylko u mnie?) ok:
wchar_t moj_napis[256]=TEXT ("Napis");
A gdzie ty tu widzisz przypisanie? Inicjalizacja a przypisanie to dwie różne rzeczy...

0

Przypisanie:
http://pl.wikipedia.org/wiki/Przypisanie

Przypisanie (podstawienie) to operacja nadania, umieszczenia, wpisania do określonej l-wartości nowej wartości.

Inicjalizacja:
http://pl.wikipedia.org/wiki/Inicjalizacja

Inicjalizacja - w programowaniu nadanie wartości/stanów początkowych obiektowi.

Nie wiem czy tak zupełnie różne rzeczy. Ale jak pisałem, dopiero zaczynam w tym temacie, więc może w WinApi jednak są to dwie zupełnie różne rzeczy - jeśli tak, poproszę o wyjaśnienie. Dzięki z góry.

0

Nie w WinAPI, tylko C++... Przypisanie używa operatora zwanego operatorem przypisania (=), inicjalizacja używa konstruktora (dla konstruktorów jednoargumentowych bez explicit można także użyć =, ale wciąż wywoływany jest konstruktor)... Zresztą przeczytaj to, co zacytowałeś. Inicjalizacja - nadanie wartości początkowej. Przypisanie - zmiana istniejącej wartości.

0

Ok dzięki.

A tak nawiasem, przed chwilą właśnie się dowiedziałem kolejnego "kruczka" w WinApi (przynajmniej w Visual Studio): zwykły time() nie działa, rzekomo _time32() i _time64() się zamiast tego używa, ale u mnie działa tylko ten ostatni.

0

Pytanie za sto punktów: jaki ma związek funkcja z biblioteki standardowej z WinAPI?

0

Odpowiedź (na razie częściowa) za 100 punktów: 'WinApi' napisałem z przekąsem. ;)

Przypuszczam, że dostęp do standardowych funkcji C/C++ można zmienić w ustawieniach w Visual Studio (dopiero zacząłem go używać). Pytanie, dlaczego Microsoft tak robi? API w większości języków rozszerza go o nowe narzędzia, ale nie zabiera "starych", czyli standardowych funkcjonalności.

0
#include <ctime>
#include <windows.h>
using namespace std;

int main()
{
	time(0);
}

U mnie się kompiluje...

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