#define STRICT
#include <windows.h>
#include <windowsx.h>
#include <dos.h>

#pragma argsused

int PASCAL
WinMain(HINSTANCE hInstance,
   HINSTANCE hPrevInstance,
   LPSTR     lpszCmdLine, int nCmdShow)
{
  BYTE szBuf[100];
  HLOCAL hmemLocal;
  HLOCAL hmemLoDiscard;
  void*  pLocal;
  void*  pLoDiscard;
  UINT   uMaxFreeMem;

  // Определяем размер доступной памяти
  uMaxFreeMem = LocalCompact(0);

  wsprintf(szBuf, "Доступно памяти:\t%u\n",
        uMaxFreeMem);
  MessageBox(NULL, (LPSTR)szBuf, "Local Block", MB_OK);

  // --------------------------------------------------------
  // Работаем с перемещаемым блоком памяти
  // --------------------------------------------------------

  // Дефрагментируем память для получения блока
  // размером 1000 байт
  uMaxFreeMem = LocalCompact(1000);

  // Заказываем буфер размером 1000 байт
  hmemLocal = LocalAlloc(GHND, 1000);

  if(hmemLocal != NULL)
  {
    // Если буфер получен, фиксируем его в памяти
    pLocal = LocalLock(hmemLocal);
    if(pLocal != NULL)
    {
      // Если блок успешно зафиксирован,
      // выводим значения идентификатора блока
      // и логический адрес блока
      wsprintf(szBuf, "hmemLocal=\t%04.4X\n"
        "pLocal=\t\t%04.4X",
        hmemLocal, pLocal);

      MessageBox(NULL, (LPSTR)szBuf, "Local Block", MB_OK);

      // -----------------------------------------
      // Можно работать с полученным блоком памяти
      // Записываем в первый байт блока символ S
      *(PSTR)pLocal = 'S';
      // -----------------------------------------

      // Разрешаем перемещение блока
      LocalUnlock(hmemLocal);
    }
    else
    {
      MessageBox(NULL, "Ошибка при фиксировании блока",
        "Local Block", MB_OK);
    }
    // Отдаем блок памяти операционной системе
    LocalFree(hmemLocal);
  }
  else
  {
    MessageBox(NULL, "Мало памяти для перемещаемого блока",
      "Local Block", MB_OK);
  }

  // --------------------------------------------------------
  // Работаем с удаляемым блоком памяти
  // --------------------------------------------------------

  // Заказываем удаляемый блок памяти размером 2000 байт
  hmemLoDiscard =
      LocalAlloc(LMEM_MOVEABLE | LMEM_DISCARDABLE, 2000);

  if(hmemLoDiscard != NULL)
  {
    // Если мы его получили, удаляем блок
    LocalDiscard(hmemLoDiscard);

    // Пытаемся зафиксировать блок памяти
    pLoDiscard = LocalLock(hmemLoDiscard);

    if(pLoDiscard != NULL)
    {
      wsprintf(szBuf, "hmemLoDiscard=\t%04.4X\n"
        "pLoDiscard=\t%04.4X",
        hmemLoDiscard, pLoDiscard);
      MessageBox(NULL, (LPSTR)szBuf, "Local Block", MB_OK);

      // Разрешаем перемещение блока
      LocalUnlock(hmemLoDiscard);
    }
    else
    {
      // Если блок памяти не удалось зафиксировать,
      // проверяем, не был ли он удален
      if(LocalFlags(hmemLoDiscard) & LMEM_DISCARDED)
      {
         MessageBox(NULL, "Блок удален и мы его восстанавливаем",
           "Local Block", MB_OK);

         // Восстанавливаем удаленный блок памяти
         hmemLoDiscard = LocalReAlloc(hmemLoDiscard, 256,
           LMEM_MOVEABLE | LMEM_DISCARDABLE);

         // Фиксируем блок памяти
         pLoDiscard = LocalLock(hmemLoDiscard);

         if(pLoDiscard != NULL)
         {
           // Выводим идентификатор и логический адрес
           // зафиксированного блока памяти
           wsprintf(szBuf, "hmemLoDiscard=\t%04.4X\n"
             "pLoDiscard=\t%04.4X",
             hmemLoDiscard, pLoDiscard);
           MessageBox(NULL, (LPSTR)szBuf, "Local Block", MB_OK);

           // Освобождаем блок памяти
           LocalUnlock(hmemLoDiscard);
         }
         else
         {
           MessageBox(NULL, "Ошибка при фиксировании блока",
           "Local Block", MB_OK);
         }
      }
    }

    // Отдаем удаляемый блок памяти операционной системе
    LocalFree(hmemLoDiscard);
  }
  else
  {
    MessageBox(NULL, "Мало памяти для удаляемого блока",
      "Local Block", MB_OK);
  }

  return 0;
}