Programming: Visual C++ - FAQ по Visual C++
Часть 2
- С помощью каких механизмов две программы могут обмениваться данными?
- Как блокировать Alt+Tab во время выполнения программы?
- Как опpеделить какой service pack установлен на NT?
- Как узнать наличие юзера сервере NT?
- Как средствами API реализовать в RichEdit разноцветный текст?
- Как пользоваться элементом управления похожим на открытие файлов, только все это для каталогов?
- Есть ли функции API, работающие с папками и файлами вместе? Как перемещать, переименовывать и копировать папки вместе с файлами, которые находятся внутри?
- Как с помощью API организовать запись с CD-ROM'а или микрофона?
- Как узнать частоту обновления экрана перед началом переключения, чтобы потом ее восстановить?
- Как узнать тип диска?
- Как удалить *.exe-файл из самого себя?
- Как изменить разрешение экрана?
- Как определить, что запущен Screen Saver?
- С помощью каких функций можно написать программу, которая использует соединения, имеющиеся в удаленном доступе?
- Как программно сжать/растянуть картинку?
- Как принудительно завершить MS-DOS задачу, не дожидаясь ее нормального выхода?
- Как нарисовать рванное окно?
- Как полностью перекрыть доступ к файлу во время работы с ним?
- Как сделать так, чтобы во время выполнения длинного метода приложение реагировало на сообщения?
- Как сделать цикличным проигрывание MIDI-файла?
- Как перехватывать ВСЕ исключения в процессе?
- Как узнать, кто в данный момент присоединен через Сеть к машине?
- Как узнать количество элементов и размер корзины? Как очистить корзину?
- Как получить список все запущенных процессов и потоков?
- Какие существуют функции для работы с COM-портом напрямую под Win9x?
- Как завесить Windows?
- Как получить hInstance консольного приложения?
- Чем отличается PID от hInstance?
- Как установить обои на Рабочий Стол?
С помощью каких механизмов две программы могут обмениваться данными?
1. OLE
2. Файлы проецируемые в память
3. Секции данных, pазделяемые несколькими пpоцессами
4. WM_COPYDATA
5. Именованные (и неименованные) каналы или pipes
6. Почтовые ячейки или mailslots
7. DDE(Dynamic data exchange).
Как блокировать Alt+Tab во время выполнения программы?
CMainFrame::CMainFrame()
{
m_nHotKeyID = 100;
BOOL m_isKeyRegistered = RegisterHotKey(GetSafeHwnd(), m_nHotKeyID,
MOD_ALT, VK_TAB);
ASSERT(m_isKeyRegistered != FALSE);
}
//Убираем блокировку при выходе из приложения
CMainFrame::~CMainFrame()
{
BOOL m_iskeyUnregistered = UnregisterHotKey(GetSafeHwnd(), m_nHotKeyID);
ASSERT(m_isKeyUnregistered != FALSE);
}
Как опpеделить какой service pack установлен на NT?
Смотрите функцию GetVersionEx.
Как узнать наличие юзера сервере NT?
NET_API_STATUS x=NetUserChangePassword(LPWSTR compname,LPWSTR username,
LPWSTR oldpassword,LPWSTR newpassword)
- где newpassword=oldpassword.
По возвращаемому значению делаем свои выводы. Дешево и сердито. И страшных прав не надо как, например, на LogonUser().
Как средствами API реализовать в RichEdit разноцветный текст?
CHARFORMAT cf;
cf.cbSize = sizeof(cf);
cf.dwMask = CFM_COLOR;
cf.crTextColor = ...; file://rgb
SendMessage(hwndRtf,EM_SETCHARFORMAT,SCF_SELECTION,(LPARAM)&cf);
Как пользоваться элементом управления похожим на открытие файлов, только все это для каталогов?
Используем API( SHGetPathFromIDList ):
LPITEMIDLIS lpItemDList;
char szWorkDir[MAX_LEN];
BROWSEINFO bi = {hWnd, NULL, m_szWorkDir,
"Выберите каталог",
BIF_DONTGOBELOWDOMAIN,
NULL,
NULL,
0
};
if(!(lpItemDList=SHBrowseForFolder(&bi))) return 0;
SHGetPathFromIDList(lpItemDList, szWorkDir);
В szWorkDir получаешь выбранный каталог.
Есть ли функции API, работающие с папками и файлами вместе? Как перемещать, переименовывать и копировать папки вместе с файлами, которые находятся внутри?
Смотрите функцию SHFileOperation.
Как с помощью API организовать запись с CD-ROM'а или микрофона?
Смотрите функции: waveInOpen, waveInPrepareHeader, waveInAddBuffer, waveInStart. Только обязательно посмотрите примеры из MSDN.
Как узнать частоту обновления экрана перед началом переключения, чтобы потом ее восстановить?
Смотрите функцию GetDeviceCaps, с паpаметpом VREFRESH
Как узнать тип диска?
Для NT все пpосто - там надо вызвать QueryDosDevice, а остальное настолько очевидно, что описывать дольше чем самому посмотpеть ;-))
Для Win95 несколько сложнее. Я не буду выкусывать соответствующий кусок из функции опpеделения типа диска. Без контекста там не совсем понятно что к чему. Hадо только учесть, что эта функция 16-ти битная и ее надо вызывать чеpез Thunk-и. Конечно, часть того, что она делает можно сделать и в 32-х битном коде, но не все.
/************************************************************************\
* Module : DrvType.cpp *
*-----------------------------------------------------------------------*
* : : Original by Micro$oft corp. from MSDN *
\************************************************************************/
/*
How to Determine Drive Types in Windows
Article ID: Q105922
*/
#include
#include
#include "..\SRC\IO_Const.h"
#pragma warning(disable:4704)
extern void FAR PASCAL DOS3Call(void);
// See the "MS-DOS Programmer's Reference" for further information
// about this structure.
typedef struct tagDEVICEPARAMS {
BYTE bSpecFunc; // Special functions
BYTE bDevType; // Device type
WORD wDevAttr; // Device attributes
WORD wCylinders; // Number of cylinders
BYTE bMediaType; // Media type
// Beginning of BIOS parameter block (BPB)
WORD wBytesPerSec; // Bytes per sector
BYTE bSecPerClust; // Sectors per cluster
WORD wResSectors; // Number of reserved sectors
BYTE bFATs; // Number of FATs
WORD wRootDirEnts; // Number of root-directory entries
WORD wSectors; // Total number of sectors
BYTE bMedia; // Media descriptor
WORD wFATsecs; // Number of sectors per FAT
WORD wSecPerTrack; // Number of sectors per track
WORD wHeads; // Number of heads
DWORD dwHiddenSecs; // Number of hidden sectors
DWORD dwHugeSectors; // Number of sectors if wSectors == 0
char Dummy[71]; // Fuck Microsoft and Microsoft's sample code!!!
// ---------------------- // End of BIOS parameter block (BPB)
} DEVICEPARAMS, FAR * LPDEVICEPARAMS;
// Function prototypes
static BOOL GetDeviceParameters (int nDrive,LPDEVICEPARAMS dp) ;
static BOOL IsCDRomDrive (int nDrive) ;
//-----------------------------------------------------------------
// GetDeviceParameters()
//
// Fills a DEVICEPARAMS struct with info about the given drive.
// Calls DOS IOCTL Get Device Parameters (440Dh, 60h) function.
//
// Parameters
// nDrive Drive number 0 = A, 1 = B, 2 = C, and so on.
// dp Pointer to a structure that will contain the drive's
// parameters.
//
// Returns TRUE if it succeeded, FALSE if it failed.
//-----------------------------------------------------------------
static BOOL GetDeviceParameters (int nDrive, LPDEVICEPARAMS dp)
{
BOOL bResult = TRUE; // Assume success
__asm {
push ds
mov bx, nDrive
inc bx // Convert 0-based #'s to 1-based #s
mov ch, 08h // Device category--must be 08h
mov cl, 60h // MS-DOS IOCTL Get Device Parameters
lds dx, dp
mov ax, 440Dh
int 21h
jnc gdp_done // CF SET if error
mov bResult, FALSE
gdp_done:
pop ds
}
return (bResult);
}
//-----------------------------------------------------------------
// IsCDRomDrive()
//
// Determines if a drive is a CD-ROM. Calls MSCDEX and checks
// that MSCDEX is loaded, and that MSCDEX reports the drive is a
// CD-ROM.
//
// Parameters
// nDrive Drive number 0 = A, 1 = B, 2 = C, and so forth.
//
// Returns TRUE if nDrive is a CD-ROM drive, FALSE if it isn't.
//-----------------------------------------------------------------
static BOOL IsCDRomDrive (int nDrive)
{
BOOL bResult = FALSE; // Assume not a CD-ROM drive
__asm {
mov ax, 150Bh // MSCDEX CD-ROM Drive Check
xor bx, bx
mov cx, nDrive
int 2Fh
cmp bx, 0ADADh // Check MSCDEX signature
jne not_cd_drive
or ax, ax // Check the drive type
jz not_cd_drive // 0 (zero) means not CD-ROM
mov bResult, TRUE
not_cd_drive:
}
return (bResult);
}
//-----------------------------------------------------------------
UINT GetDriveTypeEx (int nDrive)
{
DEVICEPARAMS dp;
UINT uType;
UINT Drv4409Flag ;
UINT fAddFlags = 0 ;
_fmemset (&dp, 0, sizeof(dp)); // Init device params struct
uType = GetDriveType (nDrive);
switch (uType) {
case DRIVE_REMOTE:
// GetDriveType() reports CD-ROMs as Remote drives. Need
-7395------------------------------------------------------------------------
// to see if the drive is a CD-ROM or a network drive.
if (IsCDRomDrive (nDrive)) {
return (EX_DRIVE_CDROM | EX_DRIVE_NOACCESS);
} else {
return (EX_DRIVE_REMOTE | EX_DRIVE_NOACCESS);
}
break;
case DRIVE_REMOVABLE:
// Check for a floppy disk drive. If it isn't, then we
// don't know what kind of removable media it is.
// For example, could be a Bernoulli box or something new...
if (GetDeviceParameters (nDrive, &dp))
switch (dp.bDevType) {
// Floppy disk drive types
case 0x0: case 0x1: // 5.25" floppy
case 0x3: case 0x4: // 8" floppy
return (EX_DRIVE_FLOPPY5);
case 0x2: case 0x7: case 0x8: // 3.5" floppy
return (EX_DRIVE_FLOPPY3);
}
return (EX_DRIVE_REMOVABLE); // Unknown removable media type
break;
case DRIVE_FIXED:
__asm {
xor dx,dx
mov bx,nDrive
inc bl // 1-'A', 2-'B',...
mov ax,0x4409
call far ptr DOS3Call
mov Drv4409Flag,dx
}
if (Drv4409Flag & 0x0100) fAddFlags |= EX_DRIVE_NOACCESS ;
// GetDeviceParameters returns a device type of 0x05 for
// hard disks. Because hard disks and RAM disks are the two
// types of fixed-media drives, we assume that any fixed-
// media drive that isn't a hard disk is a RAM disk.
if (GetDeviceParameters (nDrive, &dp) && dp.bDevType == 0x05) {
if (Drv4409Flag & 0x8000)
return (EX_DRIVE_SUBSTED | fAddFlags);
else
return (EX_DRIVE_FIXED | fAddFlags);
} else {
return (EX_DRIVE_RAMDISK | fAddFlags);
}
break;
}
return (EX_DRIVE_INVALID); // Drive is invalid if we get here.
}
Как удалить *.exe-файл из самого себя?
#include
#include
void DelSelf(void)
{
char modulename[MAX_PATH];
char batfile[MAX_PATH];
char batlines[MAX_PATH*4];
LPSTR tempdir;
char Buf[MAX_PATH];
GetModuleFileName(NULL,modulename,MAX_PATH);
tempdir = ((GetEnvironmentVariable(TEXT("TEMP"),
Buf, MAX_PATH) > 0) ? Buf : NULL);
strcpy(batfile,tempdir);
strcat(batfile,"\\");
strcat(batfile,"delself.bat");
strcpy(batlines,"@echo off\n:try\ndel ");
strcat(batlines,modulename);
strcat(batlines,"\nif exist ");
strcat(batlines,modulename);
strcat(batlines," goto try\n");
strcat(batlines,"del ");
strcat(batlines,batfile);
DWORD NOfBytes;
HANDLE hbf= CreateFile(batfile, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ
| FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
WriteFile(hbf,batlines,strlen(batlines),&NOfBytes, NULL);
CloseHandle(hbf);
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
si.wShowWindow = SW_HIDE;
si.dwFlags = STARTF_USESHOWWINDOW;
CreateProcess(
NULL,
batfile,
NULL,
NULL,
FALSE,
IDLE_PRIORITY_CLASS|DETACHED_PROCESS,
NULL,
NULL,
&si,
&pi);
}
void main()
{
DelSelf();
}
Как изменить разрешение экрана?
DEVMODE dm;
ZeroMemory(&dm,sizeof(DEVMODE));
dm.dmSize=sizeof(DEVMODE);
dm.dmBitsPerPel=16;
dm.dmPelsWidth=800;
dm.dmPelsHeight=600;
dm.dmDisplayFrequency=60;
dm.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT|DM_DISPLAYFREQUENCY;
ChangeDisplaySettings(&dm,CDS_UPDATEREGISTRY);
Как определить, что запущен Screen Saver?
Если верить справочнику по Win32 API:
bool bIsSaverActive;
SystemParametersInfo(SPI_GETSCREENSAVEACTIVE, 0, &bIsSaverActive, 0);
if (bIsSaverActive) { ... }
или
BOOL IsSaverRunning()
{ BOOL isNT;
OSVERSIONINFO ovi; ovi.dwOSVersionInfoSize=sizeof(ovi);
GetVersionEx(&ovi); isNT=(ovi.dwPlatformId==VER_PLATFORM_WIN32_NT);
if (!isNT)
{ UINT dummy, srunning=0;
BOOL res=SystemParametersInfo(SPI_SCREENSAVERRUNNING,0,&srunning,0);
SystemParametersInfo(SPI_SCREENSAVERRUNNING,srunning,&dummy,0);
if (srunning==0) return FALSE; else return TRUE;
}
// это прекрасно рабоатет под '95. Но НТ могут быть проблемы
HWND hfw=GetForegroundWindow();
if (hfw==NULL) return TRUE;
LONG wl=GetWindowLong(hfw,GWL_STYLE);
if ((wl&0xF0000000)!=WS_POPUP|WS_VISIBLE) return FALSE;
RECT rc; GetWindowRect(hfw,&rc);
if (rc.right-rc.left!=GetSystemMetrics(SM_CXSCREEN) ||
rc.bottom-rc.top!=GetSystemMetrics(SM_CYSCREEN)) return FALSE;
return TRUE;
}
С помощью каких функций можно написать программу, которая использует соединения, имеющиеся в удаленном доступе?
Смотрите Win32 API-фукнции, начинающиеся с RAS.
Как программно сжать/растянуть картинку?
Смотрите Win32 API-фукнции: StretchBlt, StretchDIBits и SetStretchBltMode.
Как принудительно завершить MS-DOS задачу, не дожидаясь ее нормального выхода?
DWORD ProcessID; //Здесь будет ProcessId, котоpый получили после CreateProcess
HANDLE hProcess;
hProcess=OpenProcess(PROCESS_TERMINATE,0,ProcessID);
if(hProcess!=NULL)
{
TerminateProcess(hProcess,0);
CloseHandle(hProcess);
}
Как нарисовать рванное окно?
...
WNDCLASS WndClass;
WndClass.lpszClassName =(LPSTR)"BalonHelp";
WndClass.hInstance =hInstance;
WndClass.lpfnWndProc =BalonWndProc;
WndClass.style =CS_SAVEBITS; // восстановление возлагаем на Win
> WndClass.hbrBackground =GetStockBrush(NULL_BRUSH);
WndClass.hCursor =LoadCursor(NULL,IDC_ARROW);
WndClass.hIcon =NULL;
WndClass.lpszMenuName =NULL;
WndClass.cbClsExtra =0;
WndClass.cbWndExtra =0;
RegisterClass(&WndClass);
...
LRESULT CALLBACK BalonWndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
switch(msg)
{
case WM_PAINT:
> // отpисовка всего окна ложится на твои плечи :-)
...
case ...
}
return DefWindowProc(hWnd,msg,wParam,lParam);
}
Как полностью перекрыть доступ к файлу во время работы с ним?
После создания с помощью следующего кода файл даже не читается:
CreateFile(f,GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
Как сделать так, чтобы во время выполнения длинного метода приложение реагировало на сообщения?
BOOL ProcessMessages()
{
MSG msgCur;
if (!::GetMessage(&msgCur, NULL, NULL, NULL))
{
return FALSE;
}
// обрабатываем это сообщение
::TranslateMessage(&m_msgCur);
::DispatchMessage(&m_msgCur);
return TRUE;
}
Как сделать цикличным проигрывание MIDI-файла?
LRESULT CMainFrame::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
if(message==MM_MCINOTIFY)
if(wParam!=MCI_NOTIFY_ABORTED)
{
if(m_bIsPlaing)
{
if(SetMidi())
PlayMidi();
}
}
return CFrameWnd::WindowProc(message, wParam, lParam);
}
BOOL CMainFrame::SetMidi()
{
StopMidi();
MCI_OPEN_PARMS OpenParm;
OpenParm.dwCallback = (DWORD)GetSafeHwnd();
OpenParm.lpstrDeviceType = NULL;
OpenParm.lpstrElementName = filename;
DWORD flags=MCI_OPEN_ELEMENT;
MCIERROR err;
err=mciSendCommand(0, MCI_OPEN, flags,(DWORD)&OpenParm);
if(!err){
m_nMidideviceID=OpenParm.wDeviceID;
return TRUE;
}
else
return FALSE;
}
BOOL CMainFrame::PlayMidi(void)
{
MCI_PLAY_PARMS PlayParm;
PlayParm.dwCallback =(DWORD)GetSafeHwnd();
PlayParm.dwFrom=0;
MCIERROR err;
err=mciSendCommand(m_nMidideviceID,MCI_PLAY,MCI_FROM|MCI_NOTIFY,(DWORD)&PlayParm);
if(!err)
{
m_bIsPlaing=TRUE;
return TRUE;
}
m_bIsPlaing=FALSE;
return FALSE;
}
BOOL CMainFrame::StopMidi(void)
{
m_bIsPlaing=FALSE;
MCI_GENERIC_PARMS generic_params;
generic_params.dwCallback=(DWORD)GetSafeHwnd();
mciSendCommand(m_nMidideviceID,MCI_CLOSE,MCI_WAIT,(DWORD)&generic_params);
return TRUE;
}
Как перехватывать ВСЕ исключения в процессе?
main()
{
try {
...
}
catch(...) {
^^^именно так и напиши!
...
}
}
Так как функция main() совсем не типична для Win32, предлагаю уделить внимание SetUnhandledExceptionFilter().
Как узнать, кто в данный момент присоединен через Сеть к машине?
Это можно узнать по сессиям:
SESSION_INFO_2 *psi2;
NET_API_STATUS Result;
wchar_t wcServerName[MAX_COMPUTERNAME_LENGTH + 1];
DWORD prefmaxlen = MAX_PREFERRED_LENGTH;
DWORD entriesread;
DWORD totalentries;
StringToWideChar( name, wcServerName, MAX_COMPUTERNAME_LENGTH );
Result = NetSessionEnum( (LPTSTR) wcServerName, NULL, NULL, 2,
(unsigned char**) &psi2, prefmaxlen, &entriesread, &totalentries, NULL );
if( Result != NERR_Success )
throw Exception("Информация о сессиях не получена!");
Как узнать количество элементов и размер корзины? Как очистить корзину?
//Очищает корзину на указанном диске
SHSTDAPI SHEmptyRecycleBin(
HWND hwnd,
LPCTSTR pszRootPath,
DWORD dwFlags);
//Получает размер и количество элементов в корзине
SHSTDAPI SHQueryRecycleBin(
LPCTSTR pszRootPath,
LPSHQUERYRBINFO pSHQueryRBInfo);
Как получить список все запущенных процессов и потоков?
Для Windows 9x используйте CreateToolhelp32Snapsot/ Process32First(Process32Next)/ Thread32First(Thread32Next).
Для WinNT - NTQuerySystemInformation. А можно так: получаете список окон в системе (каким угодно способом, если нужны только процессы - можно ограничиться top-level), далее - GetWindowTreadProcessID - получаете ID процесса (и нити). OpenProcess - дает handle процесса.
Какие существуют функции для работы с COM-портом напрямую под Win9x?
Посмотрите функции:
BuildCommDCB
BuildCommDCBAndTimeouts
ClearCommBreak
ClearCommError
CommConfigDialog
EscapeCommFunction
GetCommConfig
GetCommMask
GetCommModemStatus
GetCommProperties
GetCommState
GetCommTimeouts
GetDefaultCommConfig
PurgeComm
SetCommBreak
SetCommConfig
SetCommMask
SetCommState
SetCommTimeouts
SetDefaultCommConfig
SetupComm
TransmitCommChar
WaitCommEvent
Как завесить Windows?
1. Сделать файл system.ini больше, чем 64К. Вешается при загрузке.
2. Вызвать код:
cli
jmp $
Как получить hInstance консольного приложения?
GetModuleHandle(NULL) ;
Чем отличается PID от hInstance?
PID - уникальный идентификатор объекта ядра - процесса
Inst - (упрощенно) указатель на область памяти, куда загружен экземпляр модуля (экзешника, dll-ки)
Как установить обои на Рабочий Стол?
SystemParametrsInfo(SPI_SETDESKWALLPAPER,0,'обои.bmp',SPIF_UPDATEINIFILE);
Часть 1 | Часть 2
При перепечатке любого материала
с сайта, видимая ссылка на источник www.warayg.narod.ru
и все имена, ссылки авторов обязательны.
© 2005
|