Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Win Api
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 26.10.2010, 00:22   #1
Last
В прострации
Форумчанин
 
Регистрация: 13.01.2009
Сообщений: 239
По умолчанию Блокнот Win Api

Здравствуйте, я пытаюсь написать блокнот средствами Win Api, то есть пользоваться стандартными библиотеками нельзя, с одной оговоркой, но об этом далее. Среда разработки - codeblocks. Итак, идея в том, что в качестве параметра в программу приходит название файла, из которого надо вывести текст. Возникает проблема передачи имени файла из WinMain в WindowProcedure, но её я решил.
Следующая проблема - вёрстка текста. Некоторый аналог переноса по словам в виндовском блокноте, мне бы сделать хотя бы побуквенное. А для начала вообще хотелось бы корректно вывести текст из файла, даже без вёрстки. Оговорка: можно использовать функции из стандартных библиотек для чтения из файла и работы со строками(strlen). Вот весь код:
Код:
#include <windows.h>
#include <string.h>
#include <stdio.h>


struct List{
    const CHAR *letter;
    struct List *next;
};

void CreateList(List * start, char buffer[], int size)
{
    int i = 0;
    List *q;
    q = start;
    for (i = 0; i < size; i++)
    {
        List *p = (List *)malloc(sizeof(List));
       // q = (List *)malloc(sizeof(List));
        q->next = p;
        q->letter = &buffer[i];
        p->next = NULL;
        q = p;
    }

}

/*void PrintList(List * s)
{
	while (s->next != NULL)
    {
        //TextOut();
		s = s->next;
	}
}*/
/*  Declare Windows procedure  */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);

/*  Make the class name into a global variable  */
char szClassName[ ] = "CodeBlocksWindowsApp";

CHAR *tex;

int WINAPI WinMain (HINSTANCE hThisInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR lpszArgument,
                     int nCmdShow)
{
    HWND hwnd;               /* This is the handle for our window */
    MSG messages;            /* Here messages to the application are saved */
    WNDCLASSEX wincl;        /* Data structure for the windowclass */

    tex = lpszArgument;
    /* The Window structure */
    wincl.hInstance = hThisInstance;
    wincl.lpszClassName = szClassName;
    wincl.lpfnWndProc = WindowProcedure;      /* This function is called by windows */
    wincl.style = CS_HREDRAW | CS_VREDRAW;                 /* Catch double-clicks */
    wincl.cbSize = sizeof (WNDCLASSEX);

    /* Use default icon and mouse-pointer */
    wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
    wincl.lpszMenuName = NULL;                 /* No menu */
    wincl.cbClsExtra = 0;                      /* No extra bytes after the window class */
    wincl.cbWndExtra = 0;                      /* structure or the window instance */
    /* Use Windows's default colour as the background of the window */
    wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;

    /* Register the window class, and if it fails quit the program */
    if (!RegisterClassEx (&wincl))
        return 0;

    /* The class is registered, let's create the program*/
    hwnd = CreateWindowEx (
           0,                   /* Extended possibilites for variation */
           szClassName,         /* Classname */
           "Code::Blocks Template Windows App",       /* Title Text */
           WS_OVERLAPPEDWINDOW, /* default window */
           CW_USEDEFAULT,       /* Windows decides the position */
           CW_USEDEFAULT,       /* where the window ends up on the screen */
           544,                 /* The programs width */
           375,                 /* and height in pixels */
           HWND_DESKTOP,        /* The window is a child-window to desktop */
           NULL,                /* No menu */
           hThisInstance,       /* Program Instance handler */
           (LPVOID) lpszArgument
           );

    /* Make the window visible on the screen */
    ShowWindow (hwnd, nCmdShow);

    /* Run the message loop. It will run until GetMessage() returns 0 */
    while (GetMessage (&messages, NULL, 0, 0))
    {
        /* Translate virtual-key messages into character messages */
        TranslateMessage(&messages);
        /* Send message to WindowProcedure */
        DispatchMessage(&messages);
    }

    /* The program return-value is 0 - The value that PostQuitMessage() gave */
    return messages.wParam;
}


/*  This function is called by the Windows function DispatchMessage()  */
Тут будет разрыв, ибо иначе всё сообщение не влазит.
Пол-жизни сидючи, в монитор глядючи...

Последний раз редактировалось Last; 26.10.2010 в 00:25.
Last вне форума Ответить с цитированием
Старый 26.10.2010, 00:24   #2
Last
В прострации
Форумчанин
 
Регистрация: 13.01.2009
Сообщений: 239
По умолчанию

Код:
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    HDC         hdc;
    PAINTSTRUCT ps;
    RECT        rect;
    static char *str = NULL;
    List *start = (List *)malloc(sizeof(List));
    int size, i = 0;
    switch (message)
    {
        case WM_CREATE:
         {
                 str = (char *)(((LPCREATESTRUCT)lParam)->lpCreateParams);
                 FILE *fp;
                 fp = fopen("text.txt","r");
                 fseek(fp,0,SEEK_END);
                 size = ftell(fp);
                 rewind(fp);
                 char buffer[size];
                 fread(buffer, sizeof(char), size, fp);
                 CreateList(start, buffer, size);

                 break;
             }
        case WM_DESTROY:
        {
            PostQuitMessage (0);       /* send a WM_QUIT to the message queue */
            break;
        }
        case WM_PAINT:
        {
            hdc = BeginPaint(hwnd, &ps);
            GetClientRect(hwnd, &rect);
            TEXTMETRIC tm;
            GetTextMetrics(hdc, &tm);
            List *s;
            s = start;
            i=0;
            while (s->next != NULL)
            {
                TextOut(hdc, ++i*tm.tmAveCharWidth, 1, s->letter, 1);
                s = s->next;
            }

            EndPaint(hwnd, &ps);
            break;
        }

        default:
            return DefWindowProc (hwnd, message, wParam, lParam);
    }

    return 0;
}
Очевидно, результат работы мы видим в case: WM_PAINT. Почему-то
  1. Вывод происходит бесконечно долго.
  2. Выводятся какие-то "левые" одинаковые символы.
Хотя, если сделать вывод "посимвольно"
Код:
TextOut(hdc, ++i*tm.tmAveCharWidth, 1, s->letter, 1);
TextOut(hdc, ++i*tm.tmAveCharWidth, 1, s->next->letter, 1);
, то на экране мы видим первые два символа из текстового файла.
В общем, прошу советов мудрых, хотя, конечно, понимаю, что разбираться в такой куче кода вряд ли кто-то захочет, но сам я тут разобраться не могу.
Пол-жизни сидючи, в монитор глядючи...
Last вне форума Ответить с цитированием
Старый 26.10.2010, 00:37   #3
reynevan
Пользователь
 
Регистрация: 15.07.2010
Сообщений: 35
По умолчанию

нравится придумывать велосипед?
"Программирование для Windows 95 в двух томах" Ч. Петзолд.
Там описано все, что ты спрашиваешь и еще многое другое)
reynevan вне форума Ответить с цитированием
Старый 26.10.2010, 00:41   #4
reynevan
Пользователь
 
Регистрация: 15.07.2010
Сообщений: 35
По умолчанию

а, да, глава называется "Модернизированная программа POPPAD"
reynevan вне форума Ответить с цитированием
Старый 26.10.2010, 00:46   #5
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

зачем велосипед такой?
используйте стандартный EDIT многострочный и все.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 26.10.2010, 10:14   #6
Last
В прострации
Форумчанин
 
Регистрация: 13.01.2009
Сообщений: 239
По умолчанию

2 reynevan
Спасибо, буду читать.
2 Пепел Феникса
Есть такое слово: "надо". =)
Пол-жизни сидючи, в монитор глядючи...
Last вне форума Ответить с цитированием
Старый 29.10.2010, 21:47   #7
jungle
Пользователь
 
Аватар для jungle
 
Регистрация: 22.11.2008
Сообщений: 65
По умолчанию

Кажется, в дистрибутиве Virtual Pascal был example блокнота. (или это Борланд был)
jungle вне форума Ответить с цитированием
Старый 29.10.2010, 23:31   #8
Last
В прострации
Форумчанин
 
Регистрация: 13.01.2009
Сообщений: 239
По умолчанию

2 jungle
Гугл молчит на эту тему.
Пол-жизни сидючи, в монитор глядючи...
Last вне форума Ответить с цитированием
Старый 15.09.2011, 22:40   #9
jungle
Пользователь
 
Аватар для jungle
 
Регистрация: 22.11.2008
Сообщений: 65
По умолчанию

Код:
{
  Copyright (c) 1999 by Michael van Canneyt

  Win32 menu creation example.
}

{ Changes by G”ran Andersson:                                  major
  const FileMenus[] removed
  const filename removed
  type TFileName added
  SelectFile() added                                           *
  LoadText() added                                             *
  SaveText():
    SelectFile used                                            *
    uses GetWindowTextLength & GetWindowText
    also saves empty files
    uses untyped file
    FreeMem frees Len+1, not Len
  AskSave() added                                              *
  NewText() added                                              *
  WindowProc():
    WM_Close added
    WM_Size don't assumes StatH=16
    WM_Command 101 calls NewText
    WM_Command 102 calls LoadText
    WM_Command 104 issues a WM_Close instead of doing a Halt
  WinRegister():
    with structure used
  EditCreate():
    takes Status object as parameter
    const EditText changed to empty string
    unused variable DC removed
    WS_HScroll & WS_VScroll added to const CS_Start
    ES_AutoHScroll & ES_AutoVScroll removed from CS_Start
    don't assumes StatH=16
    AddText() commented out
  WinCreate():
    menu creation moved inside if structure
    Options menu item uses the newly created SubMenu
  main:
    slight structure change (avoid unneccesary Exit)
    call to StatusCreate before EditCreate

2do:
  make edit panel always active
  add 3d inner bevel to edit panel
  window background color : white
  only ask to save if edited
  cut
  copy
  paste
  settings
  help
}

Program menudemo;
{$APPTYPE GUI}
{$MODE DELPHI}

Uses Strings,Windows,CommDlg,CommCtrl;

Const AppName = 'MenuDemo';

Var AMessage: Msg;
    hWindow,hStatus,Hedit: HWnd;
    WindowClass: WndClass;
    Menu: hMenu;

Const
  EditMenus: Array[201..203] Of pchar = ('Cut','copy','paste');

Type
  TFileName = Array[0..Max_Path] Of Char;

Function SelectFile(Var FName:TFileName; Open:Boolean): Boolean;

Const
  Filter: PChar = 'Text files (*.txt)'#0'*.txt'#0'All files (*.*)'#0'*.*'#0;
  Ext: PChar = 'txt';

Var
  NameRec: OpenFileName;
Begin
  FillChar(NameRec,SizeOf(NameRec),0);
  FName[0] := #0;
  With NameRec Do
    Begin
      LStructSize := SizeOf(NameRec);
      HWndOwner := HWindow;
      LpStrFilter := Filter;
      LpStrFile := @FName;
      NMaxFile := Max_Path;
      Flags := OFN_Explorer Or OFN_HideReadOnly;
      If Open Then
        Begin
          Flags := Flags Or OFN_FileMustExist;
        End;
      LpStrDefExt := Ext;
    End;
  If Open Then
      SelectFile := GetOpenFileName(@NameRec)
  Else
      SelectFile := GetSaveFileName(@NameRec);
End;

Procedure SaveText;

Var Len: Longint;
    P: PChar;
    F: File;
    FName: TFileName;
Begin
  If SelectFile(FName,False) Then
    Begin
      Assign(F,@FName);
      Rewrite(F,1);
      Len := GetWindowTextLength(HEdit);
      GetMem(P,Len+1);
      P[Len] := #0;
      If Len>0 Then
        Begin
          GetWindowText(HEdit,P,Len+1);
          BlockWrite(F,P^,Len);
        End;
      Close(F);
      FreeMem(P,Len+1);
    End;
End;

Procedure AskSave;
Begin
  If MessageBox(HWindow,'Save text?','Edited',MB_IconQuestion Or MB_YesNo)=IdYes Then
    Begin
      SaveText;
    End;
End;

Procedure LoadText;

Var
  FName: TFileName;
  F: File;
  Len: LongInt;
  P: PChar;
Begin
  AskSave;
  If SelectFile(FName,True) Then
    Begin
      Assign(F,@FName);
      Reset(F,1);
      Len := FileSize(F);
      GetMem(P,Len+1);
      P[Len] := #0;
      If Len>0 Then BlockRead(F,P^,Len);
      Close(F);
      SetWindowText(HEdit,P);
      FreeMem(P,Len+1);
    End;
End;

Procedure NewText;

Const
  Empty: PChar = '';
Begin
  AskSave;
  SendMessage(HEdit,WM_SetText,1,LongInt(Empty));
End;

Последний раз редактировалось jungle; 15.09.2011 в 22:42.
jungle вне форума Ответить с цитированием
Старый 15.09.2011, 22:44   #10
jungle
Пользователь
 
Аватар для jungle
 
Регистрация: 22.11.2008
Сообщений: 65
По умолчанию

Продолжение:

Код:
Function WindowProc (Window:HWnd;AMessage : UINT; WParam : WParam; LParam:LParam): LResult;
stdcall;
export;

Var ps: paintstruct;
    r: rect;
    StatH: Word;
    nrmenu : longint;
Begin
  WindowProc := 0;
  Case AMessage Of
    wm_Paint:
              Begin
                BeginPaint(Window,@ps);
                GetClientRect(Window,@r);
                EndPaint(Window,ps);
                Exit;
              End;
    wm_Close:
              Begin
                AskSave;
              End;
    wm_Destroy:
                Begin
                  PostQuitMessage (0);
                  Exit;
                End;
    wm_Size:
             Begin
               if HStatus<>0 then
                 begin
                   GetClientRect(HStatus,@R);
                   StatH := R.Bottom-R.Top;
                   GetClientRect(Window,@R);
                   MoveWindow (hStatus,r.left,r.bottom-StatH,r.right,r.bottom,true);
                   if HEdit<>0 then
                     MoveWindow (HEdit,0,0,r.right-r.left,r.bottom-r.top-StatH,true);
                 end;
             End;
    wm_Command:
                Begin
                  NrMenu := WParam And $FFFF;
                  Case NrMenu Of
                    101 : NewText;
                    102 : LoadText;
                    103 : SaveText;
                    104 : PostMessage(Window,WM_Close,0,0);
                    201..203: MessageBox(Window,EditMenus[NrMenu],
                                         'Edit operation not implemented',MB_OK Or
                                         MB_IconInformation);
                  End;
                End;
  End;
  WindowProc := DefWindowProc(Window,AMessage,WParam,LParam);
End;

Function WinRegister: Boolean;
Begin
  With WindowClass Do
    Begin
      Style := cs_hRedraw Or cs_vRedraw;
      lpfnWndProc := WndProc(@WindowProc);
      cbClsExtra := 0;
      cbWndExtra := 0;
      hInstance := system.MainInstance;
      hIcon := LoadIcon (0,idi_Application);
      hCursor := LoadCursor (0,idc_Arrow);
      hbrBackground := GetStockObject(GRAY_BRUSH);
      lpszMenuName := 'Files';
      lpszClassName := AppName;
    End;
  Result := RegisterClass (WindowClass)<>0;
End;

Function EditCreate(ParentWindow,Status:HWnd): HWnd;

Const
  CS_Start = WS_Child or WS_HScroll or WS_VScroll or ES_MultiLine or ES_Left;
  EdiTText: PChar = '';

Var
  HEdit: HWND;
  R: TRect;
  StatH: Word;
{                                             rev 1.5 : comment out
  Procedure AddText (S:String);
  begin
    S:=S+#0;
    SendMessage(HEdit,em_replacesel,0,longint(pchar(@S[1])));
  end;
}
Begin
  GetClientRect(Status,@R);
  StatH := R.Bottom-R.Top;
  GetClientRect(ParentWindow,@R);
  HEdit := CreateWindow ('EDIT',EditText,CS_Start,0,0,
                       R.Right-R.Left,R.Bottom-R.top-StatH,ParentWindow,0,
                       System.MainInstance,Nil);
  If HEdit<>0 Then
    Begin
      ShowWindow(Hedit,cmdShow);
      UpdateWindow(HEdit);
    End;
  Result := HEdit;
End;

Function WinCreate: HWnd;

Var hWindow: HWnd;
    SubMenu: hMenu;
Begin
  hWindow := CreateWindow (AppName,'MenuDemo',ws_OverlappedWindow,
                         cw_UseDefault,cw_UseDefault,cw_UseDefault,
                         cw_UseDefault,0,0,system.MainInstance,Nil);
  If hWindow<>0 Then
    Begin
      Menu := CreateMenu;
      SubMenu := CreateMenu;
      AppendMenu(Submenu,MF_STRING,101,'&New...');
      AppendMenu(Submenu,MF_STRING,102,'&Open...');
      AppendMenu(Submenu,MF_STRING,103,'&Save...');
      AppendMenu(Submenu,MF_SEPARATOR,0,Nil);
      AppendMenu(SubMenu,MF_String,104,'E&xit');
      AppendMenu(Menu,MF_POPUP,SubMenu,'&Files');
      SubMenu := CreateMenu;
      AppendMenu(SubMenu,MF_String,201,'&Cut');
      AppendMenu(SubMenu,MF_String,202,'&Copy');
      AppendMenu(SubMenu,MF_STRING,203,'&Paste');
      AppendMenu(Menu,MF_POPUP,SubMenu,'&Edit');
      SubMenu := CreateMenu;
      AppendMenu(SubMenu,MF_String,301,'&Settings');
      AppendMenu(Menu,MF_POPUP,SubMenu,'&Options');
      AppendMenu(Menu,MF_STRING,0,'&Help');
      SetMenu(hWindow,menu);
      ShowWindow(hWindow,CmdShow);
      ShowWindow(hWindow,SW_SHOW);
      UpdateWindow(hWindow);
    End;
  Result := hWindow;
End;
jungle вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Win API ( CИ) ПроГрам Помощь студентам 0 29.04.2010 21:43
Win Api alexov Общие вопросы C/C++ 4 29.01.2009 13:33
Win API aleks_n Общие вопросы Delphi 0 15.09.2008 11:07
учебник по Win Api xTANATOSx Win Api 9 31.05.2008 16:08