СообЧа > База Знаний > Программирование > Win32 API

Вопрос

Есть ли в WINDOWS встроенная среда программирования, в которой программируют чисто в API-функциях, или обязательно нужно иметь что-то типа VisualC или Builder C++?

Ответ

Именно «встроенной» нет. А программировать чисто в API-функциях, можно практически из любой системы. Не знаю, как насчет VisualC или Builder C++, но в Delphi — без проблем. Есть и «чистые» языки типа Turbo Pascal for Windows (есть аналог и для С).
Что касается собственно «встроенной» системы, то сюда с очень большой натяжкой можно отнести только пакетные файлы (.bat) из которых, помимо их собственных команд, можно вызывать и API-функции, используя «rundll32». Например,
rundll32 user,swapmousebutton
— поменять местами кнопки мыши
Есть еще файлы сценариев, как альтернатива .BAT

Goltsov Dmitry

На дельфи очень даже просто пишется на чистом API (без форм, с «ручной» обработкой событий создания окна, прорисовки элементов и т.п.) — либо через project — view source (в файле *.dpr и пишется весь код) и удаление из проекта форм и прочего мусора. Либо создать *.pas файл и открыть как «open pascal project». Тогда Дельфи будет его нормально компилировать (иначе она считает этот файл текстом модуля и компилить его не хочет). Размер довольно функционального приложения <= 40 кб.

А идеальной с++ — шной средой разработки маленьких WIN32-API шных программ, мне показался borland c++ 5.0 — относительно мал, не перегружен лишним функционалом (как visual studio), хорошей системой помощи да и вообще :)

spam_box

Вопрос

Где где можно достать наиболее полное руководство по Win32 API. Желательно на русском?

Ответ

Очень удобным справочником (из имеющихся) в этом вопросе служит поставляемый с Borland C++ хелп по Win32 (Win32 SDK). Можно пользоваться MSDN'ом от MicroSoft, но там написано то же самое, а занимает он вместо 50М три диска! К сожалению, в этих справочниках очень мало примеров, но, к счастью, в большинстве функций параметры с мнемоническими именами, что снимает часть проблем. Из печатных справочников — трехтомник Фроловых Microsoft Windows.

******

Электронную версию «Библиотеки системного программиста» можно скачать здесь:
prog.km.ru
Есть все 34 тома.

Посмотрите также здесь:
cpp.samara.ws

******

Во-первых, первый из дисков msdn забит примерами по самую заглушку;
Во-вторых информации там раз в 100 больше, чем в win32.hlp (и она достовернее, 100%, проверено);
В-третих, msdn — это просто библия программиста. Так что мой совет — если действительно тебе надо АПИ, то купи диски, или хотя бы сделай себе копию. Я, например, каждый день в msdn сижу.

******

Отличная справка в формате hlp:
soobcha.lionovsky.us/rushelp

Вопрос

Есть ли для экрана в VB6.0 что-то типа Application.ScreenUpdating как в Excele'е?

Ответ

Субклась WM_PAIN и NC_PAINT, и когда обновление нужно запретить просто не передавай их обработчику по умолчанию.

Ivan Rozhuk

Declare Function LockWindowUpdate Lib "user32.dll" (ByVal hwndLock As Long) As Long
'блокировка обновления GUI

Sub My_Procedure
    LockWindowUpdate frmMY.hwnd 'поставить блокировку обновления
    …
    тут что-нить творится…
    …
    LockWindowUpdate 0 'снять блокирвку обновления
end sub

Сергей Л.

Вопрос

Подскажите плиз как в VB/VBA с помощью API переключить раскладку клаиватуры

(рус/англ)

Желательно полный пример, а не только название API функции.

Ответ

Для работы с раскладкой клавиатуры в VB используются три основные API-функции:

1. GetKeyboardLayout — функция GetKeyboardLayout определяет текущую раскладку клавиатуры. Если idThread равен нулю, тогда возвращается текущяя раскладка клавиатуры для данного процесса. idThread — определяет процесс (приложение). В случае верного выполнения функции возвращаемое значение — идентификатор языка(раскладка клавиатуры).

Declare Function GetKeyboardLayout Lib «user32» (ByVal IdThread As Long) As

Long.

Пример:

Private Declare Function GetKeyboardLayout Lib "user32" (ByVal dwLayout As Long) As Long Private Declare Function GetWindowThreadProcessId& Lib "user32" (ByVal hwnd As Long, lpdwProcessId As Long) As Long ' Определяет текущую раскладку клавиатуры (для данного процесса) Dim L_HKL As Long L_CHKL = GetKeyboardLayout(0) ' Определяет раскладку клавиатуры для окна другого процесса Dim hAppWnd As Long Dim ThreadID As Long Dim ThreadLayout As Long hAppWnd = FindWindow(vbNullString, "Безымянный — Блокнот") If hAppWnd = 0 Then MsgBox "Окно не найдено!" Else ThreadID = GetWindowThreadProcessId(hAppWnd, ByVal 0&) ThreadLayout = GetKeyboardLayout(ThreadID) MsgBox "Раскладка " & Hex(ThreadLayout) End If

2. ActivateKeyboardLayout — функция устанавливает идентификатор языка для текущего процесса/программы. Идентификатор языка определяет язык а также физическое размещение клавиатуры. hKL — идентификатор языка, который будет активизирован (для Windows 9х этот аргумент может быть получен при помощи LoadKeyboardLayout либо при помощи констант, приведенных ниже, для Windows NT/2k — идентификатор языка должен быть сначала загружен запросом к функции LoadKeyboardLayout). Этот аргумент должен быть либо ссылкой на клавиатурную раскладку, либо одним из следующих значений: HKL_NEXT — выбирает следующую раскладку языка (из списка языков, установленных в системе);

HKL_PREV — выбирает предыдущую раскладку языка (из списка языков, установленных в системе). Flags — Определяют различные аргументы активизации языка. Этими аргументами могут быть одни из следующих значений : KLF_REORDER, KLF_RESET, KLF_SETFORPROCESS, KLF_SHIFTLOCK, KLF_UNLOADPREVIOUS. К сожалению не могу описать значения этих констант (займет очень много места). Лучше поищи в справочнике WinApi.

Declare Function ActivateKeyboardLayout Lib "user32" (ByVal HKL As Long, ByVal Flags As Long) As Long Пример: Private Const KL_NAMELENGTH As Long = 9 Private Const HKL_NEXT As Long = 1 Private Const HKL_PREV As Long = 0 Private Declare Function ActivateKeyboardLayout Lib "user32" (ByVal HKL As Long, ByVal Flags As Long) As Long Private Declare Function GetKeyboardLayout Lib "user32" (ByVal dwLayout As Long) As Long Private Declare Function GetKeyboardLayoutName Lib "user32" Alias "GetKeyboardLayoutNameA" (ByVal pwszKLID As String) As Long Dim lC_HKL As Long Dim sC_Buffer As String Dim lS_HKL As Long Dim sS_Buffer As String ' Определяет текущую раскладку клавиатуры lC_HKL = GetKeyboardLayout(0) ' Создает буфера sC_Buffer = String(KL_NAMELENGTH — 1, 0) sS_Buffer = String(KL_NAMELENGTH — 1, 0) ' Отыскивает текущее название раскладки клавиатуры GetKeyboardLayoutName s_Buffer ' Переключается на следующую клавиатурную раскладку ActivateKeyboardLayout HKL_NEXT, 0 ' Отыскивает переключенную клавиатурную раскладку lS_HKL = GetKeyboardLayout(0) ' Возвращает название переключенной клавиатурной раскладки GetKeyboardLayoutName sS_Buffer MsgBox "Клавиатурная раскладка была переключена" & vbCrLf & "с " & sC_Buffer & "на " & sS_Buffer ' Возвращение иходной раскладки клавиатуры ActivateKeyboardLayout lC_HKL, 0

3. API функция GetKeyboardLayoutName, позволяющая узнать не просто идентификатор раскладки, а конкретное имя текущей раскладки.

Declare Function GetKeyboardLayoutName Lib «user32» Alias

"GetKeyboardLayoutNameA» (ByVal pwszKLID As String) As Long

Пример:

Dim l_HKL As Long

Dim s_Buffer As String

Private Const KL_NAMELENGTH As Long = 9

' Определяет текущую раскладку клавиатуры

l_HKL = GetKeyboardLayout(0)

s_Buffer = String(KL_NAMELENGTH — 1, 0)

' Получает название раскладки клавиатуры

GetKeyboardLayoutName sCurrent_Buffer

MsgBox «Клавиатурная раскладка -" & s_Buffer

Из конференции Expert_FAQ

Вопрос

Как в Win32API программно переместить указатель мыши в заданную точку клиентской области?

Ответ

В Win32 API есть функция BOOL SetCursorPos( int X, int Y), которая перемещает курсор мыши в заданные координаты X и Y.

Вопрос

Как в программе на ВБ активировать(развернуть, или еще что-нибудь) определенное окно?

Ответ

Есть API-функция ShowWindow.

Public Declare Function ShowWindow Lib "user32" Alias "ShowWindow" (ByVal hwnd As Long, ByVal nCmdShow As Long) As Long

Использовать:
Result = ShowWindow (hwnd, SW_SHOWMINIMIZED)

Константы посмотри в API Viewer. Они все начинаются на SW_.

Закрыть:
Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long

Использование
Result = SendMessage (hwnd, WM_CLOSE, 0&, 0&)

Константы — в API Viewer. Они все начинаются на WM_.

hwnd — это дескриптор окна.

Verter

Вопрос

Как выбрать сразу несколько файлов в диалоге открытия GetOpenFileName из «comdlg32.dll» ? Установка .lngFlags = OFN_ALLOWMULTISELECT не помогает. Подскажите пожалуйста, уже выбился из сил и людей подвожу.

Ответ

При открытии нескольких файлов проставь OFN_ALLOWMULTISELECT в Flags Если пользователь выбирает при этом несколько файлов, то в строке lpstrFile будет путь к каталогу, а далее через NULLы будут идти имена выделенных файлов, с дополнительным NULLом в конце. В nFileOffset храниться смещение имени файла, т.е. адрес по которому находится име первого файла. Формируй смещение прибавляя к базовому длинну текущего имени файла и 1 (чтобы перескочить '\0'). Ну и так пока не наткнешься на '\0' (дубль). Если пользователь выбрал один файл, то двойного NULLа в конце не будет. Смещение там не 0 и в lpstrFile сразу до '\0' храниться ПОЛНЫЙ ПУТЬ к файлу (а не к каталогу). Для выявления этого проверь не меньше ли смещение длинны первой части. Если да, то выбран один файл.

Ну и конечно же прмер на перечисление выделенных файлов, ну а там уж делай что хочешь.

void MyOpenFile(HWND hWnd) { OPENFILENAME ofn;
char szBuf[255];
char szFilter[]=TEXT("
Jpeg Files (*.*)\0*.*\0\0");
memset(&ofn, 0, sizeof(OPENFILENAME));
ofn.lStructSize =sizeof(OPENFILENAME);
ofn.hwndOwner =hWnd;
ofn.lpstrFilter =szFilter;
ofn.nFilterIndex =1L;
ofn.lpstrTitle =NULL;
ofn.lpstrFile =szBuf;
ofn.nMaxFile =sizeof(szBuf);
ofn.Flags =OFN_ALLOWMULTISELECT | OFN_EXPLORER;
if (GetOpenFileName(&ofn)) { int nOffset = ofn.nFileOffset;
// Первая часть директорий MessageBox(hWnd, ofn.lpstrFile, "Directory"
, MB_OK);
// Выделено много файлов? if (nOffset >
lstrlen(ofn.lpstrFile))
{
// Составим перечень считанных файлов while(ofn.lpstrFile[nOffset]!='\0')
{ MessageBox(hWnd, ofn.lpstrFile + nOffset, "Files"
, MB_OK);
nOffset +=strlen(ofn.lpstrFile+nOffset) + 1;
}
}
}
}
/*MyOpenFile*/


Из конференции Expert_FAQ

Вопрос

Как из программы отправить сообщение по сети на конкретный компьютер (IP и сетевое имя известны). Желательно не писать свой клиент-сервер. Хотел попробовать в программе Winsock, а получатель — WinPopup или NWPopup. Но не смог найти форматы сообщений и используемые порты.

Ответ

Вариантов, я думаю, есть очень много. Предлагаю через API обмениваться. Сделай формочку, нарисуй на ней кнопку и три текстбокса. Назови их txtFrom, txtText, txtMsg. Вставь следующий код. Запусти. Напиши имя отправителя, получателя и текст и нажми кнопку.

Option Explicit

Private Declare Function NetMessageBufferSend Lib "netapi32.dll" (ByVal ServerName As String, ByVal MsgName As String, ByVal FromName As String, Buf As Any, BufLen As Long) As Long

Private Sub Command1_Click()
Dim sName As String, sMsg As String, sBuf As String
Dim lLen As Long, ret As Long

   sName = StrConv(txtFrom.Text, vbUnicode)
   sMsg = StrConv(txtMsg.Text, vbUnicode)
   sBuf = StrConv(txtText.Text, vbUnicode)
   lLen = LenB(sBuf)
   ret = NetMessageBufferSend(sName, sMsg, sName, ByVal sBuf, ByVal lLen)

End Sub

Sergey Y. Tkachev

Вопрос

Как извлечь информацию из ресурса «Version» — полностью все данные, потому что при ответах на форумах отвечают: «Пользуйся функциями GetFileVersionInfo и VerQueryValue» или приводят пример как получить версию файла, типа Major, Minor. Мне же нужно получить FileDescription и тому подобное. Как добраться до этих данных. Пример лучше или на чистом API или на Делфи, так как в С++ я полный ноль.

Ответ

Например так:

unit Unit1; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;
type TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject);
private { Private declarations } public { Public declarations } end;
var Form1: TForm1;
iDataSize : Integer; pData : Pointer; implementation {$R *.DFM} function GetVersionString( Key : String ): String; var Dummy : Cardinal; P : Pointer;
S : String; Buffer : PChar; begin Result := '';
if iDataSize > 0 then begin VerQueryValue( pData, '\VarFileInfo\Translation', P, Dummy );
S := Format( '\StringFileInfo\%.4x%.4x\%s', [ LoWord( Integer( P^ ) ), HiWord( Integer( P^ ) ), Key ] );
if VerQueryValue( pData, PChar( S ), Pointer( Buffer ), Dummy ) then Result := StrPas( Buffer );
end;
end;
procedure GetVer(FileName : String);
var Dummy : Cardinal;
KeyNAme : String;
begin iDataSize := GetFileVersionInfoSize( PChar( FileName ), Dummy );
GetMem( pData, iDataSize );
GetFileVersionInfo( PChar( ParamStr( 0 ) ), 0, iDataSize, pData );
KeyName := 'CompanyName';
ShowMessage(KeyName + ':' + GetVersionString( KeyName ));
KeyName := 'FileDescription';
ShowMessage(KeyName + ':' + GetVersionString( KeyName ));
KeyName := 'FileVersion';
ShowMessage(KeyName + ':' + GetVersionString( KeyName ));
KeyName := 'InternalName';
ShowMessage(KeyName + ':' + GetVersionString( KeyName ));
KeyName := 'LegalCopyright';
ShowMessage(KeyName + ':' + GetVersionString( KeyName ));
KeyName := 'OriginalFilename';
ShowMessage(KeyName + ':' + GetVersionString( KeyName ));
KeyName := 'ProductName';
ShowMessage(KeyName + ':' + GetVersionString( KeyName ));
KeyName := 'ProductVersion';
ShowMessage(KeyName + ':' + GetVersionString( KeyName ));
KeyName := 'Comments';
ShowMessage(KeyName + ':' + GetVersionString( KeyName ));
KeyName := 'LegalTrademarks';
ShowMessage(KeyName + ':' + GetVersionString( KeyName )); end;
procedure TForm1.Button1Click(Sender: TObject); begin GetVer('Path_to_My_file');
end;
end.


Из конференции Expert_FAQ

Вопрос

С помощью функций WinAPI можно легко извлечь текст из таких компонентов как TButton, TMemo и т.д. С компонентом TListBox немного сложнее, но возможно. А как быть с компонентом TListView?

Ответ

Не сложнее, чем с TListBox.

uses Windows, Messages, CommCtrl; var i, Count: integer; LVItem: TLVItem; begin Count:=SendMessage(hListView, LVM_GETITEMCOUNT, 0, 0) for i:=0 to Count-1 do begin SendMessage(LVM_GETITEMTEXT, i, LParam(@LVItem)); ListBox1.Items.Add(LVItem.pszText); end; end;

Существенно, что получить данные из ListView'а можно получить только из процесса, который его создал. Т.е. из своей программы получить подписи или координаты иконок на рабочем столе так просто не получится.

Если же очень надо — почитайте о внедрении в чужие процессы.

На интересные мысли наводит, например,

http://www.rsdn.ru/article/?baseserv/hookdll.xml Из конференции Expert_FAQ

Вопрос

Необходимо использовать в своей программе регулярные выражения. Как?

Ответ

Насколько я знаю, среди стандартных библиотек Windows — нет ни одной с поддержкой регулярных выражений. В зависимости от того, какой язык Вы используете — посмотрите библиотеки регулярных выражений:

Delphi — компонент — подходит и для Borland Builder
anso.virtualave.netсам компонент
anso.virtualave.net — русский хелп

С — библиотеки:
библиотека PCRE — www.pcre.org объектная оболочка к ней — ftp://ftp.daemon.de/scip/apps/pcre++/ поддерживает диалект POSIX Regexp — www.boost.org
bazar.conectiva.com.br
download.sourceforge.net
www.geocities.com

Из конференции Expert_FAQ

Вопрос

Интересно, SetWindowLong можно использовать только в своем приложении или в любом другом? Если можно в любом, киньте примерчик или кусок кода, а то ничего не получается.

Ответ

Можно и в другом, но ты должен позаботится о том чтобы функция обработчик, адрес которой ты передаешь, была достыпна тому процессу, которому принадлежит окно, которое ты субклассиш.

Каждый процесс теоритически может адресовать 4гб памяти, те у каждого процесса свое адресное пространство, и по адресу 123456, к примеру у них хранятся разные данные, когда ты пытаешься установить обрабочик к окну др процесса, то передаешь ему адрес функции обработчика, но этот адрес находится в адресном пространстве твоей проги, а у процесса владеющего окном по этому адресу что то другое, если там данные, то может случится что то непредсказуемое, если там свободная страница памяти, то процессор тутже сгенерирует апаратное исключение ACCESS_VIOLATION, если в проге есть обработчик исключений, она может и выкарабкается, если нет то сразу вылетит.

Как субласить чужие окна я незнаю, не возникало потребности, но так точно нельзя.

Ivan Rozhuk

Вышеуказанной функцей субклассить чужие окна нельзя. Нужна по идее SetWindowLongPtr, но я сам с ней промучился много времени и в конце концов даже не смог ее правильно объявить. Вроде, в VB.NET можно легко, но я пока не пробовал. Также пакет Desaware Spyworks Tools позволяют это сделать. Но приходится таскать с собой библиотеку.

Артем Кривокрисенко

Вопрос

Делаю так:

Pixel=GetPixel(hDC,x,y)

Как можно увеличить яркость пикселя?

Ответ

Разбить на RGB составляющие и увеличить каждую в отдельности, потом обратно собрать.

Ivan Rozhuk

Вопрос

Как можно узнать HDC, зная hWnd?

Ответ

GetDC(hWnd)
GetWindowDC(hWnd)

Мартынов Сергей

Вопрос

Как можно узнать имя компьютера (сетевая идентификация), на котором в данный момент выполняется приложение?

Ответ

Используй f-ю GetComputerName(lpBuffer: PChar; var nSize: DWORD): BOOL;

— берет сабж из реестра.

procedure GetInfo(var ComputerName, UserName: String); var buf: PChar; cmp: Byte; begin cmp := 255; GetMem(buf, cmp); try GetComputerName(buf, cmp); ComputerName := buf; GetUserName(buf, cmp); UserName := buf; finally FreeMem(buf); end; end;

Из конференции Expert_FAQ

Вопрос

Как мне можно из VB управлять курсором мыши: возвращать текущее положение, устанавливать положение, производить программно нажатие?

Ответ

Чтобы получить координаты курсора следует использовать API-функцию GetCursorPos. Для установки координат мыши используется API-функция SetCursorPos.

Из конференции Expert_FAQ

Вопрос

Как определить handle маленькой иконки в файле, зная ее номер. Если ExtractIcon(handle,PChar(SourceFile),NumIcon) возвращает указатель на большую иконку, StretchDraw большой иконки в маленькую портит ее внешний вид. ExtractIconEx(PChar(FileSource),-1,nil,nil,0) не предлагать, так как нужна только одна иконка

Ответ

ExtractIconEx(PChar(FileSource),NumIcon,nil,PSmallIcon,0)

где PSmallIcon — указатель на массив хендлов видов маленькой иконки, в файле может быть записано несколько видов маленькой иконки (это считается одной иконкой…), другого способа нет…

Из конференции Expert_FAQ

Вопрос

Есть простое диалоговое приложение. Существует ли возможность определить глобальную среди всех окон горячую клавишу, которая вызывала бы такую же функцию, как один из пунктов меню, но не используя хуки?

Ответ

Вот пример по вашему запросу. Горячие клавиши регистрируются RegisterHotKey и обязательны для уничтожения (UnregisterHotKey). Для обработки использовать WndProc.

unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs; type TForm1 = class(TForm) procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); private { Private declarations } procedure WndProc(var Message: TMessage); public { Public declarations } end; var Form1: TForm1; hk_Count: Byte; implementation {$R *.dfm} procedure TForm1.WndProc(var Message: TMessage); begin if Message.Msg = WM_HOTKEY then begin MessageBox(0, 'Нажата HotKey','Информация', MB_OK + MB_ICONINFORMATION + MB_TOPMOST + MB_APPLMODAL); end; // Эту строчку не удалять!!! inherited WndProc(Message); end; procedure TForm1.FormCreate(Sender: TObject); begin Self.WindowProc := WndProc; {Ctrl+Numpad0} if not RegisterHotKey(Form1.Handle, hk_Count, MOD_CONTROL, VK_NUMPAD0) then ShowMessage('Error setting hotkey'); Inc(hk_Count); end; procedure TForm1.FormDestroy(Sender: TObject); begin UnregisterHotKey(Form1.Handle, hk_Count); end; end.

Из конференции Expert_FAQ

Вопрос

Мне нужно написать службу (сервис), которая должна запускаться до того, как пользователь вошел в систему. При логоне. Есть параметр SERVICE_SYSTEM_START у функции CreateService — но он ставится только для служб-драйверов. Как быть?

Ответ

SERVICE_AUTO_START — Specifies a device driver or service started by the service control manager automatically during system startup.
Вот примерный код по добавлению сервиса, и его настройки, выдернут из проекта, поэтому кое что придJтся поменять, в том числе нужно заменить SERVICE_DEMAND_START на SERVICE_AUTO_START, тогда при загрузке системы, сервис будет автоматом запущен

{
SC_HANDLE hSCM,hService;
if ((hSCM=OpenSCManager(0,0,SC_MANAGER_CREATE_SERVICE)))
{
lstrcat(psSettings.szAppFileName,L" -");
lstrcat(psSettings.szAppFileName,lpcszCmdLineService);
if ((hService=CreateService(hSCM,lpcszServiceName,lpcszDisplayProductName, (SERVICE_CHANGE_CONFIG | SERVICE_START),SERVICE_WIN32_OWN_PROCESS,SERVICE_DEMAND_START,SERVICE_ERROR_IGNORE, psSettings.szAppFileName,0,0,0,0
,0)))
{
SC_ACTION sca[3];
SERVICE_FAILURE_ACTIONS sfa;
SERVICE_DESCRIPTION sd;
sca[0].Delay=1000;
sca[0].Type=SC_ACTION_RESTART;
sca[1]=sca[0];
sca[2]=sca[0];
sfa.dwResetPeriod=30;
sfa.lpRebootMsg=0;
sfa.lpCommand=0;
sfa.cActions=3;
sfa.lpsaActions=&sca[0];
sd.lpDescription=(LPWSTR)lpcszServiceDescription;
if (!ChangeServiceConfig2(hService,SERVICE_CONFIG_FAILURE_ACTIONS,&sfa)) ulRet=GetLastError();
if (!ChangeServiceConfig2(hService,SERVICE_CONFIG_DESCRIPTION,&sd)) ulRet=GetLastError();
CloseServiceHandle(hService);
}else{
ulRet=GetLastError();
}
CloseServiceHandle(hSCM);
}else{
ulRet=GetLastError();
}
if (ulRet) ReportError(ulRet);
}

и код для удаления сервиса

{
SC_HANDLE hSCM,hService;
if ((hSCM=OpenSCManager(0,0,SC_MANAGER_CREATE_SERVICE)))
{
if ((hService=OpenService(hSCM,lpcszServiceName,(SERVICE_STOP | DELETE))))
{
if (!DeleteService(hService)) ulRet=GetLastError();
CloseServiceHandle(hService);
}else{
ulRet=GetLastError();
}
CloseServiceHandle(hSCM);
}else{
ulRet=GetLastError();
}
if (ulRet) ReportError(ulRet);
}

Из конференции Expert_FAQ

Вопрос

Могу ли я отключить (насовсем или ненадолго) пользователю клавиши Ctrl+PrintScreen?

Например выведя из память процедуру обработки этих клавиш средствами ВБ? Если да, то куда копать?

Ответ

В сторону RegisterHotKey.

Артем Кривокрисенко

Вопрос

Как перехватывать попытки удаления файлов, копирования, переименования и т.д.?

Ответ

Для того, чтобы отлавливать изменения в файловой системе (но, к сожалению, не фильтровать или отменять их), можно использовать функции FindFirstChangeNotification и FindNextChangeNotification. Вот пример их использования из MSDN:

DWORD dwWaitStatus;
HANDLE dwChangeHandles[2];

// Watch the C:\WINDOWS directory for file creation and
// deletion.

dwChangeHandles[0] =
dFirstChangeNotification(
"C:\\WINDOWS", // directory to watch
FALSE, // do not watch the subtree
FILE_NOTIFY_CHANGE_FILE_NAME); // watch file name changes

if (dwChangeHandles[0] == INVALID_HANDLE_VALUE)
ExitProcess(GetLastError());

// Watch the C:\ subtree for directory creation and
// deletion.

dwChangeHandles[1] = FindFirstChangeNotification(
"C:\\", // directory to watch
TRUE, // watch the subtree
FILE_NOTIFY_CHANGE_DIR_NAME); // watch dir. name changes

if (dwChangeHandles[1] == INVALID_HANDLE_VALUE)
ExitProcess(GetLastError());

// Change notification is set. Now wait on both notification
// handles and refresh accordingly.

while (TRUE)
{

// Wait for notification.

dwWaitStatus = WaitForMultipleObjects(2, dwChangeHandles,
FALSE, INFINITE);

switch (dwWaitStatus)
{
case WAIT_OBJECT_0:

// A file was created or deleted in C:\WINDOWS.
// Refresh this directory and restart the
// change notification. RefreshDirectory is an
// application-defined function.

RefreshDirectory("C:\\WINDOWS")
if ( FindNextChangeNotification(
dwChangeHandles[0]) == FALSE )
ExitProcess(GetLastError());
break;

case WAIT_OBJECT_0 + 1:

// A directory was created or deleted in C:\.
// Refresh the directory tree and restart the
// change notification. RefreshTree is an
// application-defined function.

RefreshTree("C:\\");
if (FindNextChangeNotification(
dwChangeHandles[1]) == FALSE)
ExitProcess(GetLastError());
break;

default:
ExitProcess(GetLastError());
}
}


Для того чтобы иметь более полный контроль над тем, что происходит с файлами и иметь возможность отменять или изменять запросы, посылаемые системой для чтения/записи файлов, необходимо писать свой собственный драйвер — фильтр. Бесплатная программа, демонстрирующая вариант как это можно сделать — SysInternals FileMonitor (есть версии для Win9x, WinNT и Win2K). Сайт, откуда можно скачать программы вместе с исходными текстами — www.sysinternals.com

Алексей

Вопрос

Как проще отлавливать событие MouseOut?
Обычно делаю это с помощью GetCursorPos, можно ли проще?

Ответ

Можно субклассингом, но проще через SetCapture.

Когда ты вызовешь SetCapture, твой контрол будет получать все сообщения мыши, в том числе и MouseOver, причем даже тогда, когда он выедет за пределы формы. Вот если X или Y вышли за пределы твоего контрола, то делай, что нужно.

А субклассингом:

WM_MOUSELEAVE = &H2A3&

Но только очень уж сложно заставить работать это сообщение, у меня не получилось.

В VB .NET для этого есть специальное стандартное событие.

Из конференции VB

Вопрос

Как сделать, чтобы отслеживалось, не произошло ли подключение к интернету, а если произошло, то чтобы запускался .bat-файл?

Ответ

Вариант очень прост. Кладете на форму элемент ТАЙМЕР. Установите свойство ИНТЕРВАЛ как 1000 (то есть одна секунда). Или вот вам готовый проект…

Private Declare Function RasEnumConnections Lib "RasApi32.dll" Alias
"RasEnumConnectionsA" (lpRasCon As Any, lpcb As Long, lpcConnections As
Long) As Long
Private Declare Function RasGetConnectStatus Lib "RasApi32.dll" Alias
"RasGetConnectStatusA" (ByVal hRasCon As Long, lpStatus As Any) As Long
Private Const RAS95_MaxEntryName = 256
Private Const RAS95_MaxDeviceType = 16
Private Const RAS95_MaxDeviceName = 32
Private Type RASCONN95
dwSize As Long
hRasCon As Long
szEntryName(RAS95_MaxEntryName) As Byte
szDeviceType(RAS95_MaxDeviceType) As Byte
szDeviceName(RAS95_MaxDeviceName) As Byte
End Type
Private Type RASCONNSTATUS95
dwSize As Long
RasConnState As Long
dwError As Long
szDeviceType(RAS95_MaxDeviceType) As Byte
szDeviceName(RAS95_MaxDeviceName) As Byte
End Type

Private Sub Form_Load()
Timer1.Interval = 1000
Timer1.Enabled = True
End Sub

Private Sub Timer1_Timer()
If IsConnected() = True Then
'отключите таймер, если он больше не нужен, или хотя бы приостановите
его
Timer1.Enabled = False
'здесь нужно запустить ваш bat-файл
'Не забудьте указать правильную ссылку
Call Shell("ПутьКВашемуБатнику", vbHide)
'и если нужно, снова запустите таймер, сняв маркер со следующей строчки
'Timer1.Enabled = True
End If
End Sub

Public Function IsConnected() As Boolean
Dim TRasCon(255) As RASCONN95
Dim lg As Long
Dim lpcon As Long
Dim RetVal As Long
Dim Tstatus As RASCONNSTATUS95
TRasCon(0).dwSize = 412
lg = 256 * TRasCon(0).dwSize
RetVal = RasEnumConnections(TRasCon(0), lg, lpcon)
Tstatus.dwSize = 160
RetVal = RasGetConnectStatus(TRasCon(0).hRasCon, Tstatus)
If Tstatus.RasConnState = &H2000 Then
IsConnected = True
Else
IsConnected = False
End If


Игорь Шаронов

Вопрос

1.Как получить заголовки (caption) всех запущенных программ?
2.Как например написать программно в edit другой программы?

Ответ

procedure TForm1.FormCreate(Sender: TObject);
function Enumerator(Wnd: HWND; lParam: integer): LongBool; stdcall;
var
Len: integer;
P: PChar;
begin
// получаем длину текста заголовка окна
Len:=SendMessage(Wnd, WM_GETTEXTLENGTH, 0, 0);
if Len>0 then
begin
// увеличиваем длину на один (строка должна заканчиваться нулем)
Len:=Len+1;
// выделяем память под строку
GetMem(P, Len);
// получаем текст заголовка
SendMessage(Wnd, WM_GETTEXT, Len, integer(P));
// добавляем его в ListBox
SendMessage(lParam, LB_ADDSTRING, 0, integer(P));
// освобождаем память
FreeMem(P, Len);
end;
end;
begin
// допустим, на форме имеется Listbox1: TListBox;
ListBox1.Items.Clear;
// заполняем его заголовками всех окон на текущем desktop'е
EnumWindows(@Enumerator, ListBox1.Handle);
end;


Из конференции Expert_FAQ

Вопрос

Как получить серийные номера устройств подключенных к компьютеру? Если можно пример на VBA?

Ответ

Private Declare Function GetVolumeInformation Lib "
Kernel32"
Alias "
GetVolumeInformationA" (ByVal lpRootPathName As String,
ByVal lpVolumeNameBuffer As String,
ByVal nVolumeNameSize As Long,
lpVolumeSerialNumber As Long,
lpMaximumComponentLength As Long,
lpFileSystemFlags As Long,
ByVal lpFileSystemNameBuffer As String,
ByVal nFileSystemNameSize As Long) As Long Private Sub GetInfoAboutDriveC() Dim Serial As Long,
VName As String,
FSName As String 'Create buffers VName = String$(255, Chr$(0)) FSName = String$(255, Chr$(0)) 'Get the volume information GetVolumeInformation "C:\",
VName, 255,
Serial, 0, 0, FSName, 255 'Strip the extra chr$(0)'s VName = Left$(VName,
InStr(1, VName, Chr$(0)) — 1) FSName = Left$(FSName,
InStr(1, FSName, Chr$(0)) — 1) MsgBox "The Volume name of C:\ is '" + VName + "', the File system name of C:\ is '" + FSName + "' and the serial number of C:\ is '" +
Trim(Str$(Serial)) +
"'", vbInformation + vbOKOnly,
App.Title End Sub


Из конференции Expert_FAQ

Вопрос

Как приложением, висящим в памяти, заблокировать клавиатуру?

Ответ

Предупреждение: после запуска этого кода для активизации клавиатуры вам надо перезагрузить компьютер.

Shell "rundll32 keyboard,disable"

Игорь Шаронов

Вопрос

Как можно заставить компьютер перезагрузиться или выключится?

Ответ

Выключить — ExitWindowsEx(EWX_SHUTDOWN,1);
Перезагрузить — ExitWindowsEx(EWX_REBOOT,1);

Shadow

Первый вариант — только для win9x.
На Delphi это будет выглядеть так:

procedure ShutDownSystem;
var
Handle,Ph: THandle;
pid : DWORD;
luid : TLargeInteger;
priv : TOKEN_PRIVILEGES;
ver : TOSVersionInfo;
begin
ver.dwOSVersionInfoSize:=Sizeof(ver);
GetVersionEx(ver);
if ver.dwPlatformId=VER_PLATFORM_WIN32_NT then begin
pid:=GetCurrentProcessId;
ph := OpenProcess(PROCESS_ALL_ACCESS,false,pid);
if OpenProcessToken(ph,TOKEN_ADJUST_PRIVILEGES,handle) then
if LookupPrivilegeValue(nil,'SeShutdownPrivilege',luid) then begin
priv.PrivilegeCount:=1;
priv.Privileges[0].Attributes:= SE_PRIVILEGE_ENABLED;
priv.Privileges[0].Luid:=luid;
AdjustTokenPrivileges(handle,false,priv,0,nil,pid);
end;
end;
ExitWindowsEx(EWX_POWEROFF+EWX_FORCE ,0);
end;

Вопрос

Как программно отправить компьютер в ждущий режим?

Ответ

Можно использовать три пути.

1. Функция ExitWindowsEx
BOOL ExitWindowsEx(
UINT uFlags, // флаг выключения
DWORD dwReserved // reserved
);
Parameters
uFlags
Определяет тип отключения, может быть следующим EWX_FORCE
Обрывает все процессы принудительно, если этот флаг установлен, система не посылает сообщения
WM_QUERYENDSESSION и WM_ENDSESSION работающим приложениям.
При этом возможна потеря информации!!!
EWX_LOGOFF Выключает пользователя соответсвенно…
EWX_POWEROFF Выключает комп…
EWX_REBOOT Перегружает…
EWX_SHUTDOWN Опускает систему до точки безопасного выключения питания…
dwReserved
Reserved; this parameter is ignored.
Пример: ExitWindowsEx(EWX_FORCE or EWX_REBOOT); //перегруз машины без вопросов
Это, наверное не совсем подойдет, но там можно покопаться…

2. Использовать командную строку:
rundll32 shell32,SHExitWindowsEx -1 — перегрузить Explorer
rundll32 shell32,SHExitWindowsEx 1 — выключение компьютера
rundll32 shell32,SHExitWindowsEx 0 — завершить Работу Текущего Пользователя
rundll32 shell32,SHExitWindowsEx 2 — Windows-98-PC boot
rundll32 krnl386.exe,exitkernel — выход из Windows без любых сообщений/вопросов

3. Этот наверное самый правильный — функция SetSystemPowerState
BOOL SetSystemPowerState(
BOOL fSuspend,
BOOL fForce
);
fSuspend
Метод.
Если TRUE — спящий режим (все в памяти)
Если FALSE — гибернация(HYBERNATE) — вся память скидывается на диск.
fForce
Форсирование.
Если TRUE — принудительное усыпление (возможно зависание системы при выходе),
Если FALSE — опрос приложений и драйверов для разрешения засыпания (не все драйвера это могут, поэтому некоторые машины не уходят в спящий режим)

Из конференции Expert_FAQ

Вопрос

Как и с помощью каких АПИ создается многоуровневое динамическое меню?

Ответ

В режиме дизайна никакого меню не делаешь.

1. Создаешь верхнеуровневое меню функцией CreateMenu. А потом цепляешь это меню к форме — SetMenu
2. Далее — CreatePopUpMenu. Создается подменю.
3. Добавляешь это подменю (2) в верхнеуровневое меню (его идентификатор ты получил в пункте (1)) функцией AppendMenu.
4. Выполняешь пункты 2-3 до тех пор, пока не создащь все подменю.
5. Ты заполнил верхнеуровневое меню элементами подменю. Дальше — функцией CreatePopUpMenu и AppendMenu создаешь и добавляешь подменю в созданные подменю. И так, пока не создашь все подменю для существующих подменю.

Выполняешь пункт 5 для созданных подменю и т.д. Так до тех пор, пока не создашь всю иерархию. Потом функцией AppendMenu добавляешь элементы, на которые можно будет нажимать в самые низкоуровневые подменю.

Естественно, все это Чудо нужно будет субклассить.

Артем Кривокрисенко

Вопрос

Как сделать окно любого приложения активным, если я знаю его hwnd?

Ответ

SetForegroundWindow

Savenger

Вопрос

Как сделать плавно изменяющийся цвет заголовка окна (CAPTION) средствами API?

Ответ

Базовая идея состоит в том, чтобы написать собственную функцию рисования заголовка, которая может делать что угодно (например, отрисовывать битмап), а потом обрабатывать сообщения WM_NVACTIVATE и WM_NCPAINT, которые сообщают, что надо отрисовать неклиентскую область окна, и вызывать из обработчиков свою функцию. Обратись у статье [MSDN]->[Periodicals 1997]->[Microsoft Systems Journal]->[January]->[C++ Q&A]. Там очень доходчиво разобрана и теория, и практика этой задачи.

Вопрос

Как скопировать текст в буфер обмена с помошью WinAPI?

Ответ

//копирование строки в буфер обмена
BOOL TextToClipboard(HWND hwnd, char* str)
{
if (OpenClipboard(hwnd))//открываем буфер обмена
{
if (EmptyClipboard())//очищаем буфер обмена
{
HGLOBAL clipbuffer;//буфер для хранения строки
char * buffer;//строка, помещаемая в буфер
clipbuffer = GlobalAlloc(GMEM_DDESHARE|GMEM_MOVEABLE, strlen(str)+1);//выделяем память
buffer = (char*)GlobalLock(clipbuffer); //блокируем доступ к выделенной памяти
strcpy(buffer, str);//копируем строку
GlobalUnlock(clipbuffer);//разблокируем память
SetClipboardData(CF_TEXT,clipbuffer);//записываем строку в буферобмена
if (!CloseClipboard()) return FALSE;//закрываем буферобмена
}
else
return FALSE;
}
else
return FALSE;
return TRUE;
}

Вопрос

Как узнать название диска, те обозначение (С, Д, Е…)?

Ответ

Есть функция GetLogicalDrives. Она возвращает целочисленное значение, в котором каждый бит отвечает за наличие соответствующего диска в системе:

А — бит 00
В — бит 01
С — бит 02

(все биты нумеруются с конца)

Пример (в Delphi):

var DrivesMask : Integer;
ch : char;
begin … DrivesMask := GetLogicalDrives;
for ch := 'a' to 'z' do begin
//перебираем по буквам
if LongBool(DrivesMask and 1) then
//проверяем самый первый бит …
//здесь делаете все, что хотите: диск с буквой равной ch
//присутствует в системе DrivesMask := DrivesMask shr 1;
//"сдвигаем" значение вправо,
//чтобы потом проверить следующий
//диск
end;
… end;


А вот как получить метки дисков:

{--------------------}
{ ПОЛУЧИТЬ ТИП ФАЙЛА }
{--------------------}
//это понадобится для Windows неNT function GetFileType(Path: String): String;
var SFI: TShFileInfo;
begin FillChar(SFI, sizeof(SFI), 0);
ShGetFileInfo(PChar(Path), 0, SFI, SizeOf(SFI), SHGFI_TYPENAME); Result :=
SFI.szTypeName; end;
{----------------------}
{ ПОЛУЧИТЬ МЕТКУ ДИСКА }
{----------------------}
const drv = ':\';
function GetLabelDisk(Ch: Char): String;
var st: String;
NotUsed, VolFlags: DWORD;
Buf: array [0..MAX_PATH] of Char;
begin st := '';
Buf[0] := #$00;
GetVolumeInformation(PChar(Ch + drv), Buf, DWORD(sizeof(Buf)), nil, NotUsed, VolFlags, nil, 0);
st := Buf;
if st = '' then st := GetFileType(Ch + drv);
//вот здесь та самая
//"совместимость"
Result := st;
end;


Все эти примеры взяты из очень хорошего компонента BAPDriveBox для библиотеки KOL. Компонент можно скачать по адресу
http://kol.mastak.ru
http://xcl.cjb.net

Из конференции Expert_FAQ

Вопрос

Как эмулировать мышиные клики?

Ответ

Функция Win 32 API — Mouse_Event.

Павел Сурменок

Вопрос

Какая API функция возвращает символ-разделитель между дробной и целой частью числа?

Ответ

Если Вас интересует разделитель с точки зрения региональных настроек, то можно использовать функцию FormatNumber(<выражение>,<количество десятичных знаков>, -2).
Если у Вас уже есть число и нужно получить разделитель — то можно написать свою функцию:
Function Delimiter(aNum)
dim result, aNumStr, aFracD, aFrac
'Преобразовываем число в строку (Str)
aNumStr = Str(aNum)
'Получаем его дробную часть с разделителем
aFracD = Right(aNumStr, len(aNumStr)-len(Str(fix(aNum)))+1)
'Получаем сам разделитель
aChar = Left(aFracD,1)
do while not (Asc(aChar)>=48 and Asc(aChar)<=57) and len(aFracD)>0
if not (Asc(aChar)>=48 and Asc(aChar)<=57) then result = result &
aChar
if len(aFracD)>1 then
aFracD = Right(aFracD,len(aFracD)-1)
else
aFracD = ""
end if
aChar = Left(aFracD,1)
loop
Delimiter = result
end function

Вопрос

Какая апишка возвращает модемный трафик (скорость передачи модема в данный момент) в реальном времени?

Ответ

Все зависит от типа RAS-соединения (in/out), а также, что самое важное, — от типа платформы, где будет производиться сбор статистики. Совет: посмотреть http://msdn.microsoft.com
на предмет RasAdmin*, MprAdmin* и Remote Access Service Reference.

Вопрос

Какая функция отвечат за прозрачность окон в 2000 и ХР?

Ответ

Сделать прозрачное окно можно с помощью функции SetLayeredWindowAttributes. Информацию по ней можно найти в MSDN. «Живет» эта функция в библиотеке User32.lib.

Из конференции Expert_FAQ

Вопрос

Какие команды используются в mciSendString? Я знаю только две — открытия\закрытия СДРОМа:
mciSendString ("set CDAudio door open", NULL, 0, NULL);
mciSendString ("set CDAudio door close", NULL, 0, NULL);
В справке искал — не нашел.

Ответ

Команды MCI (см. Windows SDK, Microsoft Multimedia Programmer's Reference)

MCI_BREAK — прерывание операции
MCI_CAPTURE — захват
MCI_CLOSE — закрытие доступа
MCI_CONFIGURE — конфигурирование видеоустройств
MCI_COPY — копирование в буфер
MCI_CUE — немедленное воспроизведение
MCI_CUT — перенос в буфер
MCI_DELETE — удаление
MCI_ESCAPE — прямая передача данных устройству
MCI_FREEZE — заморозка
MCI_GETDEVCAPS — статистика устройства
MCI_INDEX — включение/выключение
MCI_INFO — получение информации прямо от
устройства
MCI_LIST — информация о количестве каналов
MCI_LOAD — загрузка файла
MCI_MARK — пометка
MCI_MONITOR — указание источника видео
MCI_OPEN — открытие доступа
MCI_PASTE — вставка из буфера
MCI_PAUSE — пауза
MCI_PLAY — воспроизведение
MCI_PUT — указание источника, приемника и
размера вывода на экран
MCI_QUALITY — уровень качества
MCI_REALIZE — реализация палитры в контексте
устройства
MCI_RECORD — запись
MCI_RESERVE — выделение дискового пространства для
записи
MCI_RESTORE — захват прямо из файла
MCI_RESUME — продолжение воспроизведения
MCI_SAVE — сохранение файла
MCI_SEEK — позиционирование
MCI_SET — установка информации устройства
MCI_SETAUDIO — установка аудио-переменных
MCI_SETTIMECODE — включение/выключение захвата по времени
MCI_SETTUNER — переключение каналов
MCI_SETVIDEO — установка видео-переменных
MCI_SIGNAL — установка позиции в рабочем
пространстве
MCI_SPIN — раскрутка устройства
MCI_STATUS — информация о MCI-устройстве
MCI_STEP — передвижение на другой фрейм
MCI_STOP — остановка
MCI_SYSINFO — поиск информации об устройстве
MCI_UNDO — отмена действия
MCI_UNFREEZE — размораживание
MCI_UPDATE — обновление прямоугольника вывода
MCI_WHERE — получение координат прямоугольника
вывода
MCI_WINDOW — описание окна

Вопрос

Какие функции выполняет RunDll?

Например: Shell «RunDll KeyBoard,Disabled»

А что еще можно сделать запуская RunDll.Exe с разными параметрами коммандной строки?

Ответ

Вот некоторые из возможных применений — всех их, наверное, немеряно.

# Команда Описание

1 rundll32 user.exe,ExitWindows Завершение работы Windows

2 rundll32 user.exe,ExitWindowsExec Перезагрузка Windows

3 rundll32 shell32.dll,SHExitWindowsEx Завершение сеанса работы Windows

4 rundll32 user,WNetConnectDialog Вызвать окно «Подключение сетевого диска»

5 rundll32 user,WNetDisconnectDialog Вызвать окно «Отключение сетевого диска»

6 rundll32 user,disableoemlayer Провоцировать сбой системы (черный экран и мигающий курсор)

7 rundll32 user,RepaintScreen Обновить экран

8 rundll32 user,SetCursorPos Переместить курсор мыши в левый верхний угол

9 rundll32 diskcopy,DiskCopyRunDll Вызвать окно «Копирование диска»

10 rundll32 shell,ShellExecute Открыть корневой каталог в проводнике

11 rundll32 shell32,OpenAs_RunDLL filename.ext Открыть диалоговое окно «Открыть с помощью…» и связать указанную программу с файлами с расширением, указанном в команде

12 rundll32 shell32,SHFormatDrive Вызвать окно форматирования диска A:

13 rundll32 shell32,ShellAboutA Вызвать небольшое окошко с информацией о Windows

14 rundll32 shell32,Control_RunDLL Открыть Панель управления

15 rundll32 shell32,Control_RunDLL set.cpl Вызвать определенное окно на Панели управления. Вместо set.cpl в команде нужно вписать необходимый файл с расширением .cpl.

16 rundll32 krnl386.exe,exitkernel По идее что-то вроде EWX_FORCE, безоговорочно и без промедления завершающего работу Windows. Но у меня эта команда полностью подвесила компьютер.

17 rundll32 user,SwapMouseButton Поменять местами клавиши мыши (работает только в одну сторону)

18 rundll32 keyboard,disable Отключить клавиатуру (до перезагрузки)

19 rundll32 mouse,disable Отключить мышь (до перезагрузки)

20 rundll32 user,TileChildWindows Расположить все несвернутые окна по вертикали

21 rundll32 user,CascadeChildWindows Расположить все несвернутые окна каскадом

22 rundll32 msprint2.dll,RUNDLL_PrintTestPage Выбрать принтер и распечатать пробную страницу

23 rundll32 user,SetCaretBlinkTime Сильно увеличить частоту мигания курсора (изменяется на Панели управления)

24 rundll32 user, SetDoubleClickTime Изменить скорость двойного щелчка мыши (изменяется на Панели управления)

25 rundll32 rnaui.dll,RnaWizard Вызвать диалог «Установка связи»

26 rundll32 sysdm.cpl,InstallDevice_Rundll Установить оборудование (Windows 98)

27 rundll32 shell32,SHExitWindowsEx 0 Перезагрузить Windows без перезагрузки компьютера (Windows 98)

28 rundll32 shell32,SHExitWindowsEx 1 Завершить работу Windows (Windows 98)

29 rundll32 shell32,SHExitWindowsEx 2 Перезагрузить компьютер (Windows 98)

30 rundll32 shell32,SHExitWindowsEx -1 Перезагрузить Explorer (Windows 98)

Из конференции Expert_FAQ

Вопрос

Какой функцией можно «вытащить» имя пользователя, который в данный момент работает на данном компьюторе?

Ответ

Как узнать имя, под которым зарегистрировался пользователь а системе Win98 ?

1. //---------------------------

В uses добавить модуль Registry.

procedure TFirst.FormCreate(Sender: TObject);
var Reg: TRegistry; begin Reg := TRegistry.Create;
try Reg.RootKey := HKEY_LOCAL_MACHINE;
Reg.OpenKey('\System\CurrentControlSet\Control\ ComputerName\ComputerName',False);
showmessage('Компьютер имеет имя: '+Reg.ReadString('ComputerName'));
Reg.OpenKey('\Network\logon',False);
showmessage('Вы вошли под именем:
'+Reg.ReadString('UserName'));
finally Reg.Free;
inherited;
end;
end;


2. //-----------------------------

Procedure GetUserInfo(var CompName, UserName: String); i: Cardinal; Begin i:=sizeof(Tmp);
GetComputerName(@Tmp, i);
i:=1;
while Tmp[i]<>#0 do Inc(i);
CompName:=String(Tmp);
SetLength(CompName,i-1);
i:=sizeof(Tmp);
GetUserName(@Tmp, i);
i:=1;
while Tmp[i]<>#0 do Inc(i);
UserName:=String(Tmp);
SetLength(UserName,i-1);
End;


Из конференции Expert_FAQ

Вопрос

Нужно очень быстро выводить системное время, но(!), самое главное, в миллисекундах в расчете от какой-либо даты.

Ответ

Если тебе это подойдет: 1. DWORD GetTickCount(VOID)
возвращает количество миллисекунд с момента запуска винды
2. VOID GetSystemTime(
LPSYSTEMTIME lpSystemTime // address of system time structure
);

возвращает время по UTC
VOID GetLocalTime(
LPSYSTEMTIME lpSystemTime // address of system time structure
);


возвращает текущее время (то, что в трее)
typedef struct _SYSTEMTIME { // st
WORD wYear;
WORD wMonth;
WORD wDayOfWeek;
WORD wDay;
WORD wHour;
WORD wMinute;
WORD wSecond;
WORD wMilliseconds;
} SYSTEMTIME;


Ivan

Вопрос

Почему GetDC и GetWindowDC возвращают разные значения?

Ответ

lngHDC=GetDC(frmmain.hwnd)

Только после того, как ты с этим dc поработаешь, его надо отпустить — ReleaseDC.

А возвращают разные значения по вполне понятным причинам — когда ты используешь GetDC, для твоего окна создается устройство контекста, а когда ты его отпускаешь — оно разрушается. Потом снова берешь — оно снова создается, но хендл у него уже другой.

Артем Кривокрисенко

Потому что функции GetDC и GetWindowDC — разные.
Функция GetWindowDC предназначена для получения контекста окна, включая заголовок, меню, скроллбары, т.е. получив контекст с помощью этой функции можно рисовать в НЕклиентской области окна. Функция GetDC, предназначена для получения контекста КЛИЕНТСКОЙ области.

Вопрос

Почему в Win32API не такое представление цветов в 16-ричной системе, как в HTML? Например, в HTML $FF0000 — соответствует красному цвету, а в проектах Delphi, к примеру, при выполнении такой строчки: Panel1.Color:=$FF0000; цвет панели получается синим?

Ответ

Такой формат цвета реализован в Win32API (COLORREF). В памяти WORD, DWORD, QWORD хранятся в обратном порядке, конкретно, в нашем случае:
$AABBCCDD запишется как $DD, $CC, $BB, $AA.

Novikov Dmitry.

Вопрос

Что такое hwnd?

Ответ

hWnd является уникальным идентификатором окна в Windows. Этот параметр в основном используется при работе с API функциями.

Rafis

Вопрос

А что это за Windows API (если можно поподробнее, можно ссылку)?

Ответ

API — Application Programmable Interface, то есть программируемый интерфейс приложений — набор библиотечных функций для разработки приложений под различные ОС. Наиболее известные:
Winodws API16 — для разработки приложений под Windows 3.x
Win32S — расширения API16 для поддержки 32 разрядных приложений под Win 3.x
Windows API32 — поддержка платформ Windows 95/98, NT, CE, 2000 и т.д.
OS/2 API — поддержка OS/2 (ОС фирмы IBM)

Вообще, практически любая ОС имеет свой интерфейс для разработки приложений, который и называется API. Для DOS это, возможно, прерывание 21h — самый короткий интерфейс. Для Windows — порядка нескольких сотен различных функций (ну, большинство из них относятся к графической подсистеме — GDI)
Полностью описание Windows API доступно, например, в MSDN (Microsoft Developer Network)
msdn.microsoft.com

Шадрин

Вопрос

Хочу узнать, что такое мьютексы, как с ними работать, да и вообще любая инфа и ссылки по ним.

Ответ

Синхронизация нитей внутри процесса в ОС Windows.

Национальный Технический Университет — «Харьковский Политехнический Институт»

Кафедра «Вычислительной Техники и Программирования» © Панченко В.И.

1. Процессы, нити и волокна в ОС Windows. Дополнительные данные.

Процессом (process) называется экземпляр программы, загруженной в память. Этот экземпляр может создавать нити (thread), которые представляют собой последовательность инструкций на выполнение. Важно понимать, что выполняются не процессы, а именно нити. Причем любой процесс имеет хотя бы одну нить. Эта нить называется главной (основной) нитью приложения. Так как практически всегда нитей гораздо больше, чем физических процессоров для их выполнения, то нити на самом деле выполняются не одновременно, а по очереди (распределение процессорного времени происходит именно между нитями). Но переключение между ними происходит так часто, что кажется, будто они выполняются параллельно.

В зависимости от ситуации нити могут находиться в трех состояниях. Во-первых, нить может выполняться, когда ей выделено процессорное время, т.е. она может находиться в состоянии активности. Во-вторых, она может быть неактивной и ожидать выделения процессора, т.е. быть в состоянии готовности. И есть еще третье, тоже очень важное состояние — состояние блокировки. Когда нить заблокирована, ей вообще не выделяется время. Обычно блокировка ставится на время ожидания какого-либо события. При возникновении этого события нить автоматически переводится из состояния блокировки в состояние готовности.

Например, если одна нить выполняет вычисления, а другая должна ждать результатов, чтобы сохранить их на диск. Вторая могла бы использовать цикл типа «while( !isCalcFinished ) continue;», но легко убедиться на практике, что во время выполнения этого цикла процессор занят на 100 % (это называется активным ожиданием). Таких вот циклов следует по возможности избегать, в чем оказывает неоценимую помощь механизм блокировки. Вторая нить может заблокировать себя до тех пор, пока первая не установит событие, сигнализирующее о том, что чтение окончено.

2. Синхронизация нитей в ОС Windows.

В Windows реализована вытесняющая многозадачность — это значит, что в любой момент система может прервать выполнение одной нити и передать управление другой. Ранее, в Windows 3.1, использовался способ организации, называемый кооперативной многозадачностью: система ждала, пока нить сама не передаст ей управление и именно поэтому в случае зависания одного приложения приходилось перезагружать компьютер.

Все нити, принадлежащие одному процессу, разделяют некоторые общие ресурсы — такие, как адресное пространство оперативной памяти или открытые файлы. Эти ресурсы принадлежат всему процессу, а значит, и каждой его нити. Следовательно, каждая нить может работать с этими ресурсами без каких-либо ограничений. Но… Если одна нить еще не закончила работать с каким-либо общим ресурсом, а система переключилась на другую нить, использующую этот же ресурс, то результат работы этих нитей может чрезвычайно сильно отличаться от задуманного. Такие конфликты могут возникнуть и между нитями, принадлежащими различным процессам. Всегда, когда две или более нитей используют какой-либо общий ресурс, возникает эта проблема.

Пример. Несинхронизированная работа нитей: если временно приостановить выполнение нити вывода на экран (пауза), фоновая нить заполнения массива будет продолжать работать.

#include
#include int a[5];
HANDLE hThr;
unsigned long uThrID;
void Thread( void* pParams )
{
int i, num = 0; while (1)
{
for (i=0; i<5; i++) a[i] = num; num++;
}
}
int main( void )
{
hThr=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)Thread,NULL,0,&uThrID);
while(1) printf("%d %d %d %d %d\n", a[0], a[1], a[2], a[3], a[4]);
return 0;
}


Именно поэтому необходим механизм, позволяющий потокам согласовывать свою работу с общими ресурсами. Этот механизм получил название механизма синхронизации нитей (thread synchronization). Этот механизм представляет собой набор объектов операционной системы, которые создаются и управляются программно, являются общими для всех нитей в системе (некоторые — для нитей, принадлежащих одному процессу) и используются для координирования доступа к ресурсам. В качестве ресурсов может выступать все, что может быть общим для двух и более нитей — файл на диске, порт, запись в базе данных, объект GDI, и даже глобальная переменная программы (которая может быть доступна из нитей, принадлежащих одному процессу).

Объектов синхронизации существует несколько, самые важные из них — это взаимоисключение (mutex), критическая секция (critical section), событие (event) и семафор (semaphore). Каждый из этих объектов реализует свой способ синхронизации. Также в качестве объектов синхронизации могут использоваться сами процессы и нити (когда одна нить ждет завершения другой нити или процесса); а также файлы, коммуникационные устройства, консольный ввод и уведомления об изменении. Любой объект синхронизации может находиться в так называемом сигнальном состоянии. Для каждого типа объектов это состояние имеет различный смысл. Нити могут проверять текущее состояние объекта и/или ждать изменения этого состояния и таким образом согласовывать свои действия. При этом гарантируется, что когда нить работает с объектами синхронизации (создает их, изменяет состояние) система не прервет ее выполнения, пока она не завершит это действие. Таким образом, все конечные операции с объектами синхронизации являются атомарными (неделимыми.

3. Работа с объектами синхронизации

Чтобы создать тот или иной объект синхронизации, производится вызов специальной функции WinAPI типа Create… (напр. CreateMutex). Этот вызов возвращает дескриптор объекта (HANDLE), который может использоваться всеми нитями, принадлежащими данному процессу. Есть возможность получить доступ к объекту синхронизации из другого процесса — либо унаследовав дескриптор этого объекта, либо, что предпочтительнее, воспользовавшись вызовом функции открытия объекта (Open…). После этого вызова процесс получит дескриптор, который в дальнейшем можно использовать для работы с объектом. Объекту, если только он не предназначен для использования внутри одного процесса, обязательно присваивается имя. Имена всех объектов должны быть различны (даже если они разного типа).

Нельзя, например, создать событие и семафор с одним и тем же именем. По имеющемуся дескриптору объекта можно определить его текущее состояние. Это делается с помощью т.н. ожидающих функций. Чаще всего используется функция WaitForSingleObject. Эта функция принимает два параметра, первый из которых — дескриптор объекта, второй — время ожидания в мсек. Функция возвращает WAIT_OBJECT_0, если объект находится в сигнальном состоянии, WAIT_TIMEOUT — если истекло время ожидания, и WAIT_ABANDONED, если объект-взаимоисключение не был освобожден до того, как владеющая им нить завершилась. Если время ожидания указано равным нулю, функция возвращает результат немедленно, в противном случае она ждет в течение указанного промежутка времени. В случае, если состояние объекта станет сигнальным до истечения этого времени, функция вернет WAIT_OBJECT_0, в противном случае функция вернет WAIT_TIMEOUT. Если в качестве времени указана символическая константа INFINITE, то функция будет ждать неограниченно долго, пока состояние объекта не станет сигнальным. Очень важен тот факт, что обращение к ожидающей функции блокирует текущую нить, т.е. пока нить находится в состоянии ожидания, ей не выделяется процессорного времени.

Взаимоисключения

Объекты-взаимоисключения (мьютексы, mutex — от MUTual EXclusion) позволяют координировать взаимное исключение доступа к разделяемому ресурсу. Сигнальное состояние объекта (т.е. состояние «установлен») соответствует моменту времени, когда объект не принадлежит ни одной нити и его можно «захватить». И наоборот, состояние «сброшен» (не сигнальное) соответствует моменту, когда какая-либо нить уже владеет этим объектом. Доступ к объекту разрешается, когда нить, владеющая объектом, освободит его. Две (или более) нити могут создать мьютекс с одним и тем же именем, вызвав функцию CreateMutex. Первая нить действительно создает мьютекс, а следующие — получают дескриптор уже существующего объекта.

Это дает возможность нескольким нитям получить дескриптор одного и того же мьютекса, освобождая программиста от необходимости заботиться о том, кто в действительности создает мьютекс. Если используется такой подход, желательно установить флаг bInitialOwner в FALSE, иначе возникнут определенные трудности при определении действительного создателя мьютекса. Несколько нитей могут получить дескриптор одного и того же мьютекса, что делает возможным взаимодействие между процессами. Можно использовать следующие механизмы такого подхода:

. Дочерний процесс, созданный при помощи функции CreateProcess может наследовать дескриптор мьютекса в случае, если при создании мьютекса функцией CreateMutex был указан параметр lpMutexAttributes.

. Нить может получить дубликат существующего мьютекса с помощью функции DuplicateHandle.

. Нить может указать имя существующего мьютекса при вызове функций OpenMutex или CreateMutex.

Для того чтобы объявить взаимоисключение принадлежащим текущей нити, надо вызвать одну из ожидающих функций. Нить, которой принадлежит объект, может его «захватывать» повторно сколько угодно раз (это не приведет к самоблокировке), но столько же раз она должна будет его освобождать с помощью функции ReleaseMutex. Для синхронизации нитей одного процесса более эффективно использование критических секций. Пример. Синхронизация нитей с помощью мьютексов.

#include
#include HANDLE hMutex;
int a[5];
HANDLE hThr;
unsigned long uThrID; void Thread( void* pParams )
{
int i, num = 0; while (1)
{
WaitForSingleObject( hMutex, INFINITE );
for (i=0; i<5; i++) a[i] = num;
num++; ReleaseMutex( hMutex );
}
}
int main( void )
{
hMutex=CreateMutex( NULL, FALSE, NULL );
hThr=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)Thread,NULL,0,&uThrID);
while(1)
{
WaitForSingleObject( hMutex, INFINITE );
printf("%d %d %d %d %d\n", a[0], a[1], a[2], a[3], a[4]);
ReleaseMutex( hMutex );
}
return 0;
}


Из конференции Expert_FAQ



Copyright © 2000-2004 Сообщество Чайников
Контактная информация