Tag: winapi

Entries for tag "winapi", ordered from most recent. Entry count: 16.

Uwaga! Informacje na tej stronie mają ponad 3 lata. Nadal je udostępniam, ale prawdopodobnie nie odzwierciedlają one mojej aktualnej wiedzy ani przekonań.

Pages: > 1 2

17:18
Sat
14
Nov 2009

Executable File Path

There have been a question recently at our forum about how to get the full path of the current executable file.

First idea proposed was to use argv[0] argument from main function, but this solution is wrong. The proof is a simple example with my program called Parametrizer. As this screenshot shows, program run from the command line with current directory equal to the directory where the executable file lies results in the argv[0] being set to only file name, without the full path.

The correct solution for Windows is to use GetModuleFileName function, just like this:

char exePath[MAX_PATH];
GetModuleFileName(NULL, exePath, _countof(exePath));

Then you can extract only the directory path and append any other file name to be sure you always access files installed with your application from the correct directory refered by the full, absolute path. I'll write more about function for path string processing and the concept of current directory soon...

Comments (2) | Tags: c++ winapi | Author: Adam Sawicki | Share

21:08
Sat
08
Aug 2009

Dialog Layout Manager in MFC

Sometimes I write some tools using C++ and MFC. In the Linux world it is common that GUI windows are resizeable. In Windows its not the case, but sometimes it would be nice to be able to resize a dialog window to see more information, like more rows and colums in a list. After repositioning and resizing controls in a window with my custom code I've decided to automate this task.

There are many possible approaches to this problem. WinAPI (and thus MFC) does not provide by itself any solution to automatically align controls inside a resizeable window. Each control has just its fixed rectangle (left, top, width, height) inside parent window. Delphi VCL uses Align property to snap selected controls (like Panel containing child controls) to left, right, top or bottom edge of the window. Qt encourages to design all windows with Layouts. For example, Vertical Layout splits the window into rows and automatically adjusts controls inside, one under the other.

But the solution of my choice is the one based on .NET. Controls in Windows Forms have a property called Anchor so they can be anchored to any of four possible window edges: left, top, right and bottom. If a controls is anchored only to left and top edges, it just doesn't change its position or size. If the control is anchored to right and bottom edges (for example: a button), it changes its position as window is resized so it preserves its distance to right and bottom edge of the window. If the control is anchored to all four possible window edges, it is resized to preserve distance to all window edges same as designed (for example: a list occupying central part of the window).

I've written a class which I called DialogLayoutManager. It's very easy to use and automates control resizing and repositioning inside an MFC window. All you need to do at the beginning is to create an object of this class, register your controls with selected anchors and call Save method:

m_LayoutManager->SetControl(GetDlgItem(ID_BTN_CANCEL),
  DialogLayoutManager::ANCHOR_RIGHT | DialogLayoutManager::ANCHOR_BOTTOM);
m_LayoutManager->SetControl(GetDlgItem(ID_BTN_OK),
  DialogLayoutManager::ANCHOR_RIGHT | DialogLayoutManager::ANCHOR_BOTTOM);
m_LayoutManager->Save(this);

Layout manager remembers positions and sizes of registered controls together with starting window size. Now all you need to do when the window is resized is to call Restore method. Layout manager will adjust registered controls according to new window size and specified anchors. For example, two buttons showed above will stay in bottom-right corner of the window.

void CDialog01::OnSize(UINT nType, int cx, int cy)
{
  ...
  if (LayoutManager && LayoutManager->IsSaved())
    m_LayoutManager->Restore(this);
}

Here is the code of my DialogLayoutManager class and usage example: DialogLayoutManager.cpp. It's easy to translate this code to pure WinAPI.

Comments (1) | Tags: gui mfc winapi | Author: Adam Sawicki | Share

21:06
Tue
14
Jul 2009

Efficient Finding of Duplicated Files

I've recently wrote a tool for finding duplicated files in a given directory. I wanted to do it efficiently and here is my algoritm.

My basic idea is to first recursively enumerate all files in the directory and its subdirectories and sort their descriptions by file size. Making it this way, we can then iterate through this list and for each file look ahead to see how many other files have same size. If two files have different sizes, they are obviously not equal in terms of their content. So if there is only one file with particular size, it can just be skipped. If there are two files with same size, we must just compare them by content.

If there are many files with same size, things become more complicated, as any possible combinations of them can turn out to be identical. My solution is to compare two files by a "header" (lets say - first 1024 bytes) and if they are equal - by MD5 checksum of their whole content. Checksum of each file is lazy evaluated, so it's calculated only once, the first time its needed.

As I iterate through the sorted file list, I mark reported files not to process them again. I can do it because I ensure that if a file is reported, all other identical files are also already reported. In my real code I do the same with files I encounter errors with, but here I wanted to simplify the code.

Read full entry > | Comments (1) | Tags: algorithms winapi | Author: Adam Sawicki | Share

16:43
Sat
06
Jun 2009

MFC i Smart PropertyGrid

Używam w pracy MFC i powiem wam, że wbrew temu co się mówi (i co wcześniej powtarzałem za innymi), to wcale nie jest taka zła biblioteka. Ta dostępna w płatnych wersjach Visual C++ biblioteka do GUI to tak naprawdę cienka, obiektowa nakładka na WinAPI. Tak więc ma swoje klasy odpowiadające m.in. różnym kontrolkom interfejsu, obiektom GDI itp., ale z zestawów flag bitowych czy też zasobów z zaprojektowanymi graficznie okienkami korzysta już z tych samych, co czyste WinAPI. Nie oferuje zbyt wiele ponad to, co API systemowe, ale trochę uprzyjemnia pracę. Jeśli ktoś zna dobrze WinAPI, to nie ma kłopotów z opanowaniem MFC ani powodów do narzekań, chyba że co najwyżej na to, że biblioteka jest tym czym jest i niczym więcej.

Szukałem wczoraj rozwiązania kwestii kontrolki Property Grid dla MFC i znalazłem bibliotekę Smart PropertyGrid.MFC firmy Visualhint. Jest świetna - ładna, potężna, rozszerzalna, a dzięki dobrze zaprojektowanemu interfejsowi opartemu na wielu klasach i koncepcji iteratorów, także wygodna w użyciu. Twórcy udostępnili ją całkowicie za darmo, bo teraz rozwijają i sprzedają wersję tej kontrolki dla .NET (choć przecież platforma .NET ma taką kontrolkę w standardzie).

Smart PropertyGrid.MFC

Comments (0) | Tags: c++ gui libraries winapi visual studio | Author: Adam Sawicki | Share

00:04
Tue
03
Feb 2009

Pliki INI w WinAPI

Stare dobre pliki INI to format tekstowy do przechowywania konfiguracji. Na przykład:

[Display]
Width=1280
Height=800
FullScreen=true

Czasami ten format może się przydać, a chociaż nie jest skomplikowany, to nie każdy ma ochotę pisać do niego własny parser. Dlatego warto wiedzieć, że WinAPI zawiera proste i wygodne funkcje do obsługi plików INI. Znajdują się na dole listy Registry Functions. Można się domyślać, że z każdym wywołaniem plik jest od nowa otwierany i wczytywany, więc te funkcje nie grzeszą szybkością, ale do prostych zastosowań będą OK. Na przykład wczytanie wartości:

char Buf[256];
GetPrivateProfileString(
  "Display", // Nazwa sekcji
  "FullScreen", // Nazwa klucza
  "false", // Wartość domyślna
  Buf, _countof(Buf), // Bufor wyjściowy
  FileName); // Nazwa pliku INI ze ścieżką

Comments (0) | Tags: winapi | Author: Adam Sawicki | Share

21:13
Fri
03
Oct 2008

Crash Dump

Życie programu w Windows nie kończy się wraz z błędem ochrony pamięci albo dzieleniem przez zero. Takie błędy można łapać, a co więcej, można z nich tworzyć tzw. Crash Dump - plik DMP, który wysłany do programisty może mu pomóc zlokalizować problem.

Należy objąć swój kod w sekcję __try { ... } __except ( MojaFunkcja( GetExceptionInformation() ) ) { }, a w swojej funkcji wywołać MiniDumpWriteDump pochodzącą z biblioteki Dbghelp. Ta biblioteka z kolei rozprowadzana jest jako Debugging Tools for Windows, ale do użycia tej funkcji wystarczy wersja domyślna z Windows XP.

Potem plik DMP można otworzyć w Visual C++ (rozszerzenie jest z nim domyślnie skojarzone). Trzeba jeszcze posiadać plik PDB z symbolami (powstaje w czasie kompilacji obok EXE/DLL) i już można zobaczyć gdzie wystąpił błąd, analizując np. stos wywołań Call Stack. Można nawet ściągnąć symbole do bibliotek systemowych. Ścieżki do symboli ustawia się w Tools > Options > Debugging > Symbols, lokalizacja z symbolami od bibliotek systemowych to http://msdl.microsoft.com/download/symbols.

Niestety sprawa nie jest taka prosta. Dodatkowo można na przykład postawić tzw. "Symbol Server" (to po prostu specjalny katalog zarządzany przez dedykowane programy z pakietu Debugging Tools for Windows), a podczas używania tych mechanizmów pojawia się wiele problemów (może ktoś coś poradzi na mój problem? :)

Comments (2) | Tags: c++ winapi | Author: Adam Sawicki | Share

21:22
Thu
21
Aug 2008

Raw Input

Trafiłem ostatnio na ciekawą, a mało chyba znaną część WinAPI - Raw Input. Pozwala ona na otrzymywanie przez okno komunikatów WM_INPUT z informacjami od podłączonych do komputera klawiatur, myszek i innych urządzeń wejściowych, jak joystick, ekran dotykowy czy nawet mikrofon. Celowo napisałem w liczbie mnogiej - to API pozwala na obsługę i rozróżnianie wielu podłączonych do komputera myszek i klawiatur! Ponadto daje dostęp do informacji od myszy w wyżej rozdzielczości, niż standardowa.

Ale coś za coś. Raw Input nie przetwarza za to przyspieszenia kursora Pointer Ballistics, do którego przyzwyczajeni są użytkownicy. Dlatego ten artykuł zaleca, aby do obsługi kursora stosować standardowy WM_MOUSEMOVE, do poruszania kamerą i wszędzie gdzie przyda się duża precyzja - Raw Input, a DirectInput stosować tylko do obsługi manipulatorów (joysticki, pady, kierownice).

Na koniec ciekawostka: Jest też darmowa, wieloplatformowa biblioteka do obsługi wielu myszek - ManyMouse.

Comments (2) | Tags: winapi | Author: Adam Sawicki | Share

20:35
Thu
07
Aug 2008

Odpalić program i poczekać

Jak uruchomić z poziomu swojego programu inny program i zaczekać na jego zakończenie? Funkcji do uruchamiania programów jest wiele. Najprostsza, ale posiadająca małe możliwości jest funkcja system z biblioteki standardowej C, która pozwala uruchomić dowolne polecenie systemowe. Prosta jest też funkcja WinExec, ale ona jest przestarzała i niezalecana.

Pośród tych potężnych zostają dwie, z których każda ma swoje wady i zalety. ShellExecute i ShellExecuteEx pozwala "uruchomić" dowolny plik lub wykonać na nim inną akcję powłoki (np. "open", "edit", "print"). W przypadku plików EXE to będzie uruchomienie, a dla różnych dokumentów, ich otwarcie w domyślnej aplikacji skojarzonej z rozszerzeniem. Z kolei funkcja CreateProcess pozwala uruchomić plik wykonywalny podając przy tym m.in. własne zmienne środowiskowe czy też uchwyty przechwytujące konsolowe wejście-wyjście. Zwraca natomiast uchwyt do utworzonego procesu.

Ostatnio wyczytałem, że funkcja ShellExecuteEx też potrafi zwrócić uchwyt do utworzonego procesu. Wystarczy w strukturze SHELLEXECUTEINFO ustawić pole fMask na flagę SEE_MASK_NOCLOSEPROCESS. Wówczas pole hProcess zostanie wypełnione uchwytem. Potem wystarczy już tylko poczekać na zakończenie programu takim wywołaniem:

WaitForSingleObject(shell_execute_info.hProcess, INFINITE);

Comments (0) | Tags: winapi | Author: Adam Sawicki | Share

Pages: > 1 2

STAT NO AD [Stat] [Admin] [STAT NO AD] [pub] [Mirror] Copyright © 2004-2016 Adam Sawicki
Copyright © 2004-2016 Adam Sawicki