+7(960) 250-82-68 spam@mirossa.ru


 mirossa        1С           C         PHP       JAVA       MCU  


Статьи
 
 

Куски кода

winApi. Получить скриншот и записать в файл.

//компил¤ци¤:
//cd "C:\Program Files\mingw-w64\x86_64-8.1.0-win32-seh-rt_v6-rev0\mingw64\bin"
//
//x86_64-w64-mingw32-gcc.exe winApi_PrintScreen_SaveToFile.c  -l:libgdi32.a  -o winApi_PrintScreen_SaveToFile.exe
//

//Taking screenshots in C using Win32 api.
//Code sources:
//https://pastebin.com/HNSn3qrJ
//MSDN
 
#include <Windows.h>
#include <stdio.h>
 
BOOL SaveToFile(HBITMAP hBitmap, LPCSTR lpszFileName)
{
  HDC hDC;
 
  int iBits;
 
  WORD wBitCount;
 
  DWORD dwPaletteSize=0, dwBmBitsSize=0, dwDIBSize=0, dwWritten=0;
 
  BITMAP Bitmap;
 
  BITMAPFILEHEADER bmfHdr;
 
  BITMAPINFOHEADER bi;
 
  LPBITMAPINFOHEADER lpbi;
 
  HANDLE fh, hDib, hPal,hOldPal=NULL;
 
  hDC = CreateDCA("DISPLAY", NULL, NULL, NULL);
  iBits = GetDeviceCaps(hDC, BITSPIXEL) * GetDeviceCaps(hDC, PLANES);
  DeleteDC(hDC);
  if (iBits <= 1)
    wBitCount = 1;
  else if (iBits <= 4)
    wBitCount = 4;
  else if (iBits <= 8)
    wBitCount = 8;
  else
    wBitCount = 24;
  GetObject(hBitmap, sizeof(Bitmap), (LPSTR)&Bitmap);
  bi.biSize = sizeof(BITMAPINFOHEADER);
  bi.biWidth = Bitmap.bmWidth;
  bi.biHeight = Bitmap.bmHeight;
  bi.biPlanes = 1;
  bi.biBitCount = wBitCount;
  bi.biCompression = BI_RGB;
  bi.biSizeImage = 0;
  bi.biXPelsPerMeter = 0;
  bi.biYPelsPerMeter = 0;
  bi.biClrImportant = 0;
  bi.biClrUsed = 0;
  dwBmBitsSize = ((Bitmap.bmWidth * wBitCount + 31) / 32) * 4 * Bitmap.bmHeight;
 
  hDib = GlobalAlloc(GHND,dwBmBitsSize + dwPaletteSize + sizeof(BITMAPINFOHEADER));
  lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);
  *lpbi = bi;
 
  hPal = GetStockObject(DEFAULT_PALETTE);
  if (hPal)
  {
    hDC = GetDC(NULL);
    hOldPal = SelectPalette(hDC, (HPALETTE)hPal, FALSE);
    RealizePalette(hDC);
  }
 
 
  GetDIBits(hDC, hBitmap, 0, (UINT) Bitmap.bmHeight, (LPSTR)lpbi + sizeof(BITMAPINFOHEADER)
    +dwPaletteSize, (BITMAPINFO *)lpbi, DIB_RGB_COLORS);
 
  if (hOldPal)
  {
    SelectPalette(hDC, (HPALETTE)hOldPal, TRUE);
    RealizePalette(hDC);
    ReleaseDC(NULL, hDC);
  }
 
  fh = CreateFileA(lpszFileName, GENERIC_WRITE,0, NULL, CREATE_ALWAYS,
    FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
 
  if (fh == INVALID_HANDLE_VALUE)
    return FALSE;
 
  bmfHdr.bfType = 0x4D42; // "BM"
  dwDIBSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwPaletteSize + dwBmBitsSize;
  bmfHdr.bfSize = dwDIBSize;
  bmfHdr.bfReserved1 = 0;
  bmfHdr.bfReserved2 = 0;
  bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER) + dwPaletteSize;
 
  WriteFile(fh, (LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER), &dwWritten, NULL);
 
  WriteFile(fh, (LPSTR)lpbi, dwDIBSize, &dwWritten, NULL);
  GlobalUnlock(hDib);
  GlobalFree(hDib);
  CloseHandle(fh);
  return TRUE;
}
 
int main()
{
        HDC dcScreen, dcDest;
        RECT screen;
        HBITMAP screenshot;
        BOOL res;
 
        printf("Press enter to take a screenshot!");
        getchar();
 
        dcScreen = GetWindowDC(NULL); //Gets the DC for the entire screen;
        GetWindowRect(GetDesktopWindow(), &screen);
        dcDest = CreateCompatibleDC(dcScreen);
        screenshot = CreateCompatibleBitmap(dcScreen, screen.right, screen.bottom);
        SelectObject(dcDest, screenshot);
        BitBlt(dcDest, 0, 0, screen.right, screen.bottom, dcScreen, 0, 0, SRCCOPY);
        ReleaseDC(NULL, dcScreen);
        DeleteDC(dcDest);
 
		res = SaveToFile(screenshot, "C:\\scrShts\\bbbb.bmp");
        printf("%d\n", res);
 
        return 0;
}



winApi. Создаем List View, добавляем колонки, устанавливаем цвета ячеек.

ListView_winApi.png
//  http://www.frolov-lib.ru/books/bsp.old/v22/ch3.html
//  http://www.masm32.com/board/index.php?topic=279.0
//  https://www.codeproject.com/Articles/2890/Using-ListView-control-under-Win-API
//  https://docs.microsoft.com/ru-ru/windows/win32/controls/nm-customdraw-list-view
//  https://docs.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-nmcustomdraw


//компил¤ци¤:
//cd "C:\Program Files\mingw-w64\x86_64-8.1.0-win32-seh-rt_v6-rev0\mingw64\bin"
//
//x86_64-w64-mingw32-gcc.exe winApi_ListView_coloredItems.c  -l:libgdi32.a  -o winApi_ListView_coloredItems.exe -mwindows
//

#include <windows.h>
#include <commctrl.h>
#include <string.h> 
#include <stdio.h>
 
 #define LVM_SETEXTENDEDLISTVIEWSTYLE (LVM_FIRST+54) //почему-то в commctrl.h не находит
// #define LVS_EX_FULLROWSELECT 32					//почему-то в commctrl.h не находит
 
// Прототип функции обработки сообщений с пользовательским названием:
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
HWND hList;

long long ID_LIST    = 10003;

LVCOLUMN LvCol; // Make Coluom struct for ListView
LVITEM LvItem;  // ListView Item struct

char testT[60];
DWORD dw;
 
int WINAPI WinMain(HINSTANCE hInst, // дескриптор экземпляра приложения
                   HINSTANCE hPrevInst, // не используем
                   LPSTR lpCmdLine, // не используем
                   int nCmdShow) // режим отображения окна
{
    TCHAR szClassName[] = "Mein Kampf"; // строка с именем класса
    MSG msg; // создём экземпляр структуры MSG для обработки сообщений
    WNDCLASSEX wc; // создаём экземпляр, для обращения к членам класса WNDCLASSEX
    wc.cbSize        = sizeof(wc); // размер структуры (в байтах)
    wc.style         = CS_HREDRAW | CS_VREDRAW; // стиль класса окна
    wc.lpfnWndProc   = WndProc; // указатель на пользовательскую функцию
    wc.lpszMenuName  = NULL; // указатель на имя меню (у нас его нет)
    wc.lpszClassName = szClassName; // указатель на имя класса
    wc.cbWndExtra    = 0; // число освобождаемых байтов в конце структуры
    wc.cbClsExtra    = 0; // число освобождаемых байтов при создании экземпляра приложения
    wc.hIcon         = LoadIcon(NULL, IDI_WINLOGO); // декриптор пиктограммы
    wc.hIconSm       = LoadIcon(NULL, IDI_WINLOGO); // дескриптор маленькой пиктограммы (в трэе)
    wc.hCursor       = LoadCursor(NULL, IDC_ARROW); // дескриптор курсора
    wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); // дескриптор кисти для закраски фона окна
    wc.hInstance     = hInst; // указатель на строку, содержащую имя меню, применяемого для класса
    if(!RegisterClassEx(&wc)){
        // в случае отсутствия регистрации класса:
        MessageBox(NULL, "Error of registering a main window's class!", "Err_Err", MB_OK);
        return 1; // возвращаем, следовательно, выходим из WinMain
    }
    
    // Функция, создающая окно:
	HWND hMainWnd; // создаём дескриптор будущего окна
    hMainWnd = CreateWindow(
        szClassName, // имя класса
        "List View", // заголовок окна
        WS_OVERLAPPEDWINDOW,              // | WS_VSCROLL, // режимы отображения окна
        CW_USEDEFAULT, // позиция окна по оси х
        0, // позиция окна по оси у (раз дефолт в х, то писать не нужно)
        CW_USEDEFAULT, // ширина окна
        0, // высота окна (раз дефолт в ширине, то писать не нужно)
        NULL, // дескриптор родительского окна
        NULL, // дескриптор меню
        hInst, // дескриптор экземпляра приложения
        NULL); // ничего не передаём из WndProc
    if(!hMainWnd){
        // в случае некорректного создания окна (неверные параметры и тп):
        MessageBox(NULL, "Error of creating a ListView's window!", "Err_Err2", MB_OK);
        return 0;
    }
	
	
	///////////////////////////////////////////////////////
	
	ShowWindow(hMainWnd, nCmdShow); // отображаем окно
    UpdateWindow(hMainWnd); // обновляем окно
    while(GetMessage(&msg, NULL, 0, 0)){ // извлекаем сообщения из очереди, посылаемые фу-циями, ОС
        TranslateMessage(&msg); // интерпретируем сообщения
        DispatchMessage(&msg); // передаём сообщения обратно ОС
    }
    return msg.wParam; // возвращаем код выхода из приложения
}
 
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam){
    HDC hDC; // создаём дескриптор ориентации текста на экране
    PAINTSTRUCT ps; // структура, сод-щая информацию о клиентской области (размеры, цвет и тп)
    RECT rect; // стр-ра, определяющая размер клиентской области
    COLORREF colorText = RGB(255, 0, 0); // задаём цвет текста
	
	LPNMLVCUSTOMDRAW lpNMCustomDraw;
	int i;
	char Temp[255];
	
	switch(uMsg){
		
	case WM_CREATE:
		
		
		//////////////////listView /////////////////////////////
		// LVS_REPORT  - Список отображается в виде детального отчета, состоящего из нескольких столбцов. 
		// Без него колонки не отображаются
		hList = CreateWindow(WC_LISTVIEW,NULL, LVS_EDITLABELS | LVS_REPORT | WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_BORDER,
		30, 30, 600, 100, hWnd, (HMENU)ID_LIST , NULL, 0);
		
		
		//get the handle: hList = GetDlgItem(hWnd,ID_LIST);
		
		// Here we put the info on the column headers
		// this is not data, only name of each header we like
		memset(&LvCol,0,sizeof(LvCol));                  // Zero Members
		LvCol.mask= LVCF_FMT | LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;    // Type of mask
		LvCol.cx=0x40;                                   // width between each column
		LvCol.pszText="Item";                            // First Header Text
		LvCol.cx=0x60;                                   // width of column
		LvCol.fmt = LVCFMT_RIGHT; //LVCFMT_LEFT;
		
		// For more information that our list control can supply us, we can use the extended styles (full raw select):
		SendMessage(hList,LVM_SETEXTENDEDLISTVIEWSTYLE, 0,LVS_EX_FULLROWSELECT); // Set style
		
		// Now, let us put some columns (as much as you like):
		// Inserting Couloms as much as we want
		SendMessage(hList,LVM_INSERTCOLUMN,0,(LPARAM)&LvCol); // Insert/Show the column
		LvCol.pszText="Sub Item1";                            // Next column
		SendMessage(hList,LVM_INSERTCOLUMN,1,(LPARAM)&LvCol); // ...
		LvCol.pszText="Sub Item2";                            //
		SendMessage(hList,LVM_INSERTCOLUMN,2,(LPARAM)&LvCol); //
		LvCol.pszText="Sub Item3";                            //
		SendMessage(hList,LVM_INSERTCOLUMN,3,(LPARAM)&LvCol); //
		LvCol.pszText="Sub Item4";                            //
		SendMessage(hList,LVM_INSERTCOLUMN,4,(LPARAM)&LvCol); //
		LvCol.pszText="Sub Item5";                            //
		SendMessage(hList,LVM_INSERTCOLUMN,5,(LPARAM)&LvCol); // ...same as above
		
		memset(&LvItem,0,sizeof(LvItem)); // Zero struct's Members
		
		//  Setting properties Of items:

		LvItem.mask = LVIF_TEXT; // Text Style
		LvItem.cchTextMax = 256; // Max size of text
		LvItem.iItem=0;          // choose item  
		LvItem.iSubItem=0;       // Put in first column
		LvItem.pszText="Item 0"; // Text to display (can be from a char variable) (Items)
		
		
		SendMessage(hList,LVM_INSERTITEM,0,(LPARAM)&LvItem); // Send info to the Listview

				for(i=1;i<=5;i++) // Add SubItems in a loop
				{
					LvItem.iSubItem=i;
					sprintf(Temp,"SubItem %d",i);
					LvItem.pszText=Temp;
//SetLastError(0);					
					SendMessage(hList,LVM_SETITEM,0,(LPARAM)&LvItem); // Enter text to SubItems
/*dw = GetLastError(); 
sprintf(testT, "errorCode = %d", dw);
MessageBox(hWnd, testT, TEXT(""), 0);						
*/				}
		
		
		break;
		///////////////////////////////////////////
	
	case WM_NOTIFY:
				switch (((LPNMHDR)lParam)->code)     // (LPNMLVCUSTOMDRAW->nmcd).hdr.code 
				{
				case NM_CUSTOMDRAW:
						// https://docs.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-nmlvcustomdraw
						// LPNMHDR   https://docs.microsoft.com/en-us/windows/win32/api/richedit/ns-richedit-nmhdr
				
					if (((LPNMHDR)lParam)->idFrom == ID_LIST)   //от listView
					{
						//MessageBox(hWnd, TEXT("NM_CUSTOMDRAW from ListView"), TEXT(""), 0);
						lpNMCustomDraw = (LPNMLVCUSTOMDRAW) lParam;   
						
						switch(lpNMCustomDraw->nmcd.dwDrawStage) 
								{
									case CDDS_PREPAINT : //Before the paint cycle begins
										//request notifications for individual listview items
										return CDRF_NOTIFYITEMDRAW;
											
									case CDDS_ITEMPREPAINT: //Before an item is drawn
										{
											return CDRF_NOTIFYSUBITEMDRAW;
										}
										break;
								
									case CDDS_SUBITEM | CDDS_ITEMPREPAINT: //Before a subitem is drawn
										{
											switch(lpNMCustomDraw->iSubItem)
											{
												case 0:
												{
												  lpNMCustomDraw->clrText   = RGB(255,255,255);
												  lpNMCustomDraw->clrTextBk = RGB(240,55,23);
												  
												  return CDRF_NEWFONT;
												}
												break;
												
												case 1:
												{
												  lpNMCustomDraw->clrText   = RGB(255,255,0);
												  lpNMCustomDraw->clrTextBk = RGB(0,0,0);
												  return CDRF_NEWFONT;
												}
												break;  

												case 2:
												{
												  lpNMCustomDraw->clrText   = RGB(20,26,158);
												  lpNMCustomDraw->clrTextBk = RGB(200,200,10);
												  return CDRF_NEWFONT;
												}
												break;

												case 3:
												{
												  lpNMCustomDraw->clrText   = RGB(12,15,46);
												  lpNMCustomDraw->clrTextBk = RGB(200,200,200);
												  return CDRF_NEWFONT;
												}
												break;

												case 4:
												{
												  lpNMCustomDraw->clrText   = RGB(120,0,128);
												  lpNMCustomDraw->clrTextBk = RGB(20,200,200);
												  return CDRF_NEWFONT;
												}
												break;

												case 5:
												{
												  lpNMCustomDraw->clrText   = RGB(255,255,255);
												  lpNMCustomDraw->clrTextBk = RGB(0,0,150);
												  return CDRF_NEWFONT;
												}
												break;

											}
							 
										}
								}
								return CDRF_DODEFAULT;
					}
					break; 

				}
		
	
	break;
		
	case WM_COMMAND:
    
    break;
	
    case WM_DESTROY: 
        PostQuitMessage(0); // отправляем WinMain() сообщение WM_QUIT
        break;
    default:
        return DefWindowProc(hWnd, uMsg, wParam, lParam); // если закрыли окошко
    }
    return 0;
}

winApi. change the master volume in Windows / регулировка громкости в Windows.

masterVolume
// change the master volume in Windows / регулировка громкости в Windows

// переписал с C++ на C
// в оригинальном коде есть конструкция __uuidof для получения CLSID. Не смог её ни использовать, ни
// найти рабочий аналог. Поэтому нужные CLSID брал как константные строки. Они есть в том же виде в 
// mmdeviceapi.h и endpointvolume.h .
// { в реестре есть только BCDE0395-E52F-467C-8E3D-C4579291692E ( MMDeviceEnumerator class  MMDevApi.dll ) :
//
// HKEY_CLASSES_ROOT\CLSID\{BCDE0395-E52F-467C-8E3D-C4579291692E}              
// HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{BCDE0395-E52F-467C-8E3D-C4579291692E}
// HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{BCDE0395-E52F-467C-8E3D-C4579291692E}
// HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Wow6432Node\CLSID\{BCDE0395-E52F-467C-8E3D-C4579291692E}
// HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Classes\CLSID\{BCDE0395-E52F-467C-8E3D-C4579291692E}
//
// }
// тестировал на windows 8
// Устанавливается значение, переданное в приложение через параметры.
// параметры:
// -d value        // value in the range from -64.0 to 0; use func GetVolumeRange() 
// -f value        // "scalar"; value in the range from 0.0 to 1.0.

// Компиляция
//cd "C:\Program Files\mingw-w64\x86_64-8.1.0-win32-seh-rt_v6-rev0\mingw64\bin"
//x86_64-w64-mingw32-gcc.exe 15_mute.c -lole32 -o 15_mute.exe
// 15_mute.exe


// from windows.h
/* Some kludge for Obj-C.
   For Obj-C the 'interface' is a keyword, but interface is used
   in midl-code too.  To resolve this conflict for at least the
   main windows API header, we define it here temporary.  
#ifdef __OBJC__
#pragma push_macro("interface")
#undef interface
#define interface struct
#endif
*/

//#include "stdafx.h"
#include <stdio.h>
#include <windows.h>
#include <mmdeviceapi.h>
#include <endpointvolume.h>

void Usage()
{
    printf("Usage: \n");
    printf(" SetVolume [Reports the current volume]\n");
    printf(" SetVolume -d <new volume in decibels> [Sets the current default render device volume to the new volume]\n");
    printf(" SetVolume -f <new volume as an amplitude scalar> [Sets the current default render device volume to the new volume]\n");

}
//int _tmain(int argc, _TCHAR* argv[])
int main(int argc, char * argv[])
{
    HRESULT hr;
    short int decibels = 0;
    short int scalar = 0;
    double newVolume;
    if (argc != 3 ) //&& argc != 1)
    {
	
        Usage();
        return -1;
    }
    if (argc == 3)
    {
		
        if (argv[1][0] == '-')
        {
            if (argv[1][1] == 'f')
            {
                scalar = 1;
            }
            else if (argv[1][1] == 'd')
            {
                decibels = 1;
            }
        }
        else
        {
            Usage();
            return -1;
        }

        newVolume = atof(argv[2]);
    }
printf("newVolume = %f\n\n", newVolume);
    // -------------------------
	
	// 'const IID * const    aka 'const struct _GUID * const'
	// 'CLSID'               aka 'const struct _GUID'
	
		
	CLSID lcsid;
	HRESULT rez;
	
	wchar_t* clsid_str = L"{bcde0395-e52f-467c-8e3d-c4579291692e}";
			// (LPCOLESTR)"{bcde0395-e52f-467c-8e3d-c4579291692e}"   // improperly
			
	// IID_MMDeviceEnumerator		
	rez = CLSIDFromString( clsid_str, &lcsid);
	
	if (rez == NOERROR)
		printf("NOERROR\n");
	else if (rez == CO_E_CLASSSTRING)
		printf("CO_E_CLASSSTRING\n");
	else if (rez == REGDB_E_CLASSNOTREG)
		printf("REGDB_E_CLASSNOTREG\n");
	else if (rez == REGDB_E_READREGDB)
		printf("REGDB_E_READREGDB\n");
	
	// IID_IMMDeviceEnumerator
	CLSID lcsid2;
	
	wchar_t* clsid_str2 = L"{a95664d2-9614-4f35-a746-de8db63617e6}";
			
	// IID_MMDeviceEnumerator		
	rez = CLSIDFromString( clsid_str2, &lcsid2);
	
	if (rez == NOERROR)
		printf("NOERROR\n");
	else if (rez == CO_E_CLASSSTRING)
		printf("CO_E_CLASSSTRING\n");
	else if (rez == REGDB_E_CLASSNOTREG)
		printf("REGDB_E_CLASSNOTREG\n");
	else if (rez == REGDB_E_READREGDB)
		printf("REGDB_E_READREGDB\n");
	
	// IAudioEndpointVolume
	
	CLSID lcsid3;
	
	wchar_t* clsid_str3 = L"{5cdf2c82-841e-4546-9722-0cf74078229a}";   // from endpointvolume.h
			
	// IID_MMDeviceEnumerator		
	rez = CLSIDFromString( clsid_str3, &lcsid3);
	
	if (rez == NOERROR)
		printf("NOERROR\n");
	else if (rez == CO_E_CLASSSTRING)
		printf("CO_E_CLASSSTRING\n");
	else if (rez == REGDB_E_CLASSNOTREG)
		printf("REGDB_E_CLASSNOTREG\n");
	else if (rez == REGDB_E_READREGDB)
		printf("REGDB_E_READREGDB\n");
	
	
/*	тут что-то не работает (REGDB_E_CLASSNOTREG)
	LPOLESTR lplpszProgID = NULL;   // OLECHAR **
	
	rez = ProgIDFromCLSID(&lcsid, &lplpszProgID);
	if (rez == S_OK)
		printf("S_OK\n");
	else if (rez == REGDB_E_CLASSNOTREG)
		printf("REGDB_E_CLASSNOTREG\n");
	else if (rez == REGDB_E_READREGDB)
		printf("REGDB_E_READREGDB\n");
*/	
	
	
	
	const CLSID CLSID_MMDeviceEnumerator = lcsid; //__uuidof(MMDeviceEnumerator);
	const CLSID CLSID_IMMDeviceEnumerator = lcsid2; // __uuidof(IMMDeviceEnumerator)
	
    CoInitialize(NULL);
    IMMDeviceEnumerator *deviceEnumerator = NULL;
    hr = CoCreateInstance( &CLSID_MMDeviceEnumerator, NULL, CLSCTX_INPROC_SERVER, &CLSID_IMMDeviceEnumerator, (LPVOID *)&deviceEnumerator);
	if (hr == S_OK)
		printf("S_OK\n");
	else if (hr == REGDB_E_CLASSNOTREG)
		printf("REGDB_E_CLASSNOTREG\n");
	else if (hr == CLASS_E_NOAGGREGATION)
		printf("CLASS_E_NOAGGREGATION\n");
	else if (hr == E_NOINTERFACE)
		printf("E_NOINTERFACE\n");
	else if (hr == E_POINTER)
		printf("E_POINTER\n");
	
    IMMDevice *defaultDevice = NULL;

	
	hr = deviceEnumerator->lpVtbl->GetDefaultAudioEndpoint(deviceEnumerator, eRender, eConsole, &defaultDevice); // C
	if (hr == S_OK)
		printf("S_OK\n");
	else 
		printf(" -- not  S_OK\n");
	//hr = deviceEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &defaultDevice);    //C++
	
	
    //deviceEnumerator->Release();                       //C++
	deviceEnumerator->lpVtbl->Release(deviceEnumerator); //C
    deviceEnumerator = NULL;


    IAudioEndpointVolume *endpointVolume = NULL;
	
	const CLSID CLSID_IAudioEndpointVolume = lcsid3; //__uuidof(IAudioEndpointVolume);
	
    //hr = defaultDevice->Activate(&CLSID_IAudioEndpointVolume, CLSCTX_INPROC_SERVER, NULL, (LPVOID *)&endpointVolume);  //C++
	hr = defaultDevice->lpVtbl->Activate(defaultDevice, &CLSID_IAudioEndpointVolume, CLSCTX_INPROC_SERVER, NULL, (LPVOID *)&endpointVolume);
    if (hr == S_OK)
		printf("S_OK (IMMDevice::Activate)\n");
	else 
		printf(" -- not  S_OK (IMMDevice::Activate)\n");
	
	//defaultDevice->Release();  //C++
	defaultDevice->lpVtbl->Release(defaultDevice);// C
	
    defaultDevice = NULL;

    // -------------------------
    float currentVolume = 0;
    //endpointVolume->GetMasterVolumeLevel(¤tVolume);  //C++
	endpointVolume->lpVtbl->GetMasterVolumeLevel(endpointVolume, ¤tVolume);// C
	
	
    printf("Current volume in dB is: %f\n", currentVolume);

    //hr = endpointVolume->GetMasterVolumeLevelScalar(¤tVolume);  //C++
	hr = endpointVolume->lpVtbl->GetMasterVolumeLevelScalar(endpointVolume, ¤tVolume);// C
	if (hr == S_OK)
		printf("S_OK (GetMasterVolumeLevelScalar)\n");
	else 
		printf(" -- not  S_OK (GetMasterVolumeLevelScalar)\n");
	
    printf("Current volume as a scalar is: %f\n", currentVolume);
    if (decibels)
    {
        //hr = endpointVolume->SetMasterVolumeLevel((float)newVolume, NULL);  //C++
		hr = endpointVolume->lpVtbl->SetMasterVolumeLevel(endpointVolume, (float)newVolume, NULL);// C
		if (hr == S_OK)
			printf("S_OK (SetMasterVolumeLevel)\n");
		else 
			printf(" -- not  S_OK (SetMasterVolumeLevel)\n");
    }
    else if (scalar)
    {
        //hr = endpointVolume->SetMasterVolumeLevelScalar((float)newVolume, NULL);  //C++
		hr = endpointVolume->lpVtbl->SetMasterVolumeLevelScalar(endpointVolume,(float)newVolume, NULL);// C
		if (hr == S_OK)
			printf("S_OK (SetMasterVolumeLevelScalar)\n");
		else 
			printf(" -- not  S_OK (SetMasterVolumeLevelScalar)\n");
    }
    
    
	//endpointVolume->Release();  //C++
	endpointVolume->lpVtbl->Release(endpointVolume);// C
	
    CoUninitialize();
/**/	
	
    return 0;
}

// нашёл тут https://stackoverflow.com/questions/3046668/how-to-mute-microphone-in-windows-7-with-c-c
//но оригинал здесь https://docs.microsoft.com/en-us/archive/blogs/larryosterman/how-do-i-change-the-master-volume-in-windows-vista
// там на C++

24-разрядный bmp (Bitmap Picture). Чтение, запись, перевёртывание по вертикали.

//cd "C:\Program Files\mingw-w64\x86_64-8.1.0-win32-seh-rt_v6-rev0\mingw64\bin"
//x86_64-w64-mingw32-gcc.exe bmp_24bit_read_write.c -o bmp_24bit_read_write.exe
// bmp_24bit_read_write.exe

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
     
     
    struct
    {
        short signature;
        int size;
        int adress;
        int lengthHead;
        int lenght;
        int heigh;
        short numColPlosk;
        short bitPerPix;
        int comprMet;
        int arrLenght;
        int gorResolution;
        int vertResolution;
        int numColors;
        int numMainColors;
    } headBMP;
     
    char *pic;      // BGR BGR BGR ...
	     // ( для получения из 24-х разрядов 16-битное представление цвета нужно отбросить (сдвиг) младшие разряды
		 //  у каждого канала. Так как чаще 16-битный цвет - это 5 бит "R" + 6 бит "G" + 5 бит "B", то
		 //  отбрасываем три младших бита от каналов R и B и два - от канала G.
		 //
		 //  #define TRUE2HI(rgb)      ((HICOLOR)((((rgb)&0xF80000)>>19)|(((rgb)&0xFC00)>>5)|(((rgb)&0xF8)<<8)))
		//   #define HI2TRUE(col)      ((((col)&0xF800)>>8)|(((col)&0x07E0)<<5)|(((col)&0x001F)<<19))
		//	 TRUE - это dword, с RGB значением, HI (HICOLOR) - word, с 5-6-5 RGB значением. 
		// )
    void readPic(char *path)
    {
        long int i;
        FILE *pFile;
        pFile=fopen(path, "rb");
        if(pFile == NULL) {printf("error open pFile"); exit(1);}
        else
        {
            fread(&headBMP.signature, sizeof(short), 1, pFile);
            if(headBMP.signature != (short)0x4d42){printf("pFile not bmp");exit(1);}
            else
            {
                fread(&headBMP.size, sizeof(int), 1, pFile);
                fseek(pFile,2*sizeof(short), SEEK_CUR);
                fread(&headBMP.adress, sizeof(int), 1, pFile);
                fread(&headBMP.lengthHead, sizeof(int), 1, pFile);
                fread(&headBMP.lenght, sizeof(int), 1, pFile);
                fread(&headBMP.heigh, sizeof(int), 1, pFile);
                fread(&headBMP.numColPlosk, sizeof(short), 1, pFile);
                fread(&headBMP.bitPerPix, sizeof(short), 1, pFile);
                if(headBMP.bitPerPix !=(short)24){printf("Bmp is not 24\n"); exit (1);}         
                else
                {
                    fread(&headBMP.comprMet, sizeof(int), 1, pFile);
                    fread(&headBMP.arrLenght, sizeof(int), 1, pFile);
                    fread(&headBMP.gorResolution, sizeof(int), 1, pFile);
                    fread(&headBMP.vertResolution, sizeof(int), 1, pFile);
                    fread(&headBMP.numColors, sizeof(int), 1, pFile);
                    fread(&headBMP.numMainColors, sizeof(int), 1, pFile);
                }
            }
            pic=(char*)malloc(3*headBMP.heigh*headBMP.lenght*sizeof(char));
            if(pic==0){printf("Not ram\n");exit (1);}
                else
                {
                    fseek(pFile,54*sizeof(char),SEEK_SET);
                    for (i=0;i<3*headBMP.heigh*headBMP.lenght; i++)
                    {
                        if(i%(3*headBMP.lenght)==0 && i !=0)
                        {
                            fseek(pFile,sizeof(char)*((headBMP.arrLenght-(3*headBMP.lenght*headBMP.heigh))/headBMP.heigh), SEEK_CUR);
                        }
                        fread(&pic[i],sizeof(char),1,pFile);
						
						//printf("%hhx\n", (unsigned char)pic[i] );
						printf("%hhu\n", (unsigned char)pic[i] );
						
                    }
                }
            }
        fclose(pFile);
    }
    void writePic(char *path)
    {
        long int i;
        FILE *pFile;
        pFile=fopen(path, "wb");
        if(pFile==NULL)
        {
            printf("error with open");
        }
        else
        {
            fwrite(&headBMP.signature,sizeof(short),1,pFile);
            fwrite(&headBMP.size, sizeof(int),1,pFile);
            fseek(pFile,2*sizeof(short),SEEK_CUR);
            fwrite(&headBMP.adress,sizeof(int),1,pFile);
            fwrite(&headBMP.lengthHead,sizeof(int),1,pFile);
            fwrite(&headBMP.lenght,sizeof(int),1,pFile);
            fwrite(&headBMP.heigh,sizeof(int),1,pFile);
            fwrite(&headBMP.numColPlosk,sizeof(short),1,pFile);
            fwrite(&headBMP.bitPerPix,sizeof(short),1,pFile);
            fwrite(&headBMP.comprMet,sizeof(int),1,pFile);
            fwrite(&headBMP.arrLenght,sizeof(int),1,pFile);
            fwrite(&headBMP.gorResolution,sizeof(int),1,pFile);
            fwrite(&headBMP.vertResolution,sizeof(int),1,pFile);
            fwrite(&headBMP.numColors,sizeof(int),1,pFile);
            fwrite(&headBMP.numMainColors,sizeof(int),1,pFile);
     
            fseek(pFile, 54*sizeof(char), SEEK_SET);
            for(i=0;i<3*headBMP.heigh*headBMP.lenght;i++)
            {
                if(i%(3*headBMP.lenght)==0 && i !=0)
                {
                    fseek(pFile,sizeof(char)*((headBMP.arrLenght-(3*headBMP.lenght*headBMP.heigh))/headBMP.heigh), SEEK_CUR);
                }
                fwrite(&pic[i],sizeof(char),1,pFile);
            }
            for(i=0;i<((headBMP.arrLenght-(3*headBMP.lenght*headBMP.heigh))/headBMP.heigh);i++)
            {
                fwrite(&pic[1],sizeof(char),1,pFile);
            }
        }
        fclose(pFile);
    }
    void verticalReflectC()
    {
        char buf = 0x00;
        int i,k;
        for (i=0;i<headBMP.heigh/2;i++)
        {
            for(k=0;k<headBMP.lenght*3;k++)
            {
                buf=pic[k+(headBMP.lenght*3)*i];
                pic[k+(headBMP.lenght*3)*i]=pic[(headBMP.heigh-i-1)*headBMP.lenght*3+k];
                pic[(headBMP.heigh-i-1)*headBMP.lenght*3+k]=buf;
            }
        }
    }
    int main( int argc, char** argv )
    {
        readPic("1.bmp");
        verticalReflectC();
        writePic("result.bmp");
        free(pic);
        return 0;
    }

//  https://studassistent.ru/c/otobrazhenie-kartinki-bmp-c-si

to be continued...