Few Questions

Hello, yesterday I started writing my hex editor. It's not fiished but here it is:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
// main.cpp

#include <windows.h> 
#include "hex.h"

LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
char szClassName[ ] = "WindowsApp";

int WINAPI WinMain (HINSTANCE hThisInstance,
                    HINSTANCE hPrevInstance,
                    LPSTR lpszArgument,
                    int nFunsterStil)

{
    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 */

    wincl.hInstance = hThisInstance;
    wincl.lpszClassName = szClassName;
    wincl.lpfnWndProc = WindowProcedure;      /* This function is called by windows */
    wincl.style = CS_DBLCLKS;                 /* Catch double-clicks */
    wincl.cbSize = sizeof (WNDCLASSEX);

    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 */
    wincl.hbrBackground = (HBRUSH) COLOR_3DFACE;

    if (!RegisterClassEx (&wincl))
        return 0;

    hwnd = CreateWindowEx (
           WS_EX_CLIENTEDGE,                   /* Extended possibilites for variation */
           szClassName,         /* Classname */
           "Windows App",       /* Title Text */
           WS_OVERLAPPEDWINDOW, /* default window */
           50,       // reik padaryt nepriklausoma nuo situ s.
           40,       
           640,                 /* The programs width */
           600,                 /* and height in pixels */
           HWND_DESKTOP,        /* The window is a child-window to desktop */
           NULL,                /* No menu */
           hThisInstance,       /* Program Instance handler */
           NULL                 /* No Window Creation data */
           );

    ShowWindow (hwnd, nFunsterStil);
    while (GetMessage (&messages, NULL, 0, 0))
    {
        TranslateMessage(&messages);
        DispatchMessage(&messages);
    }
    return messages.wParam;
}

LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {

        case WM_PAINT:
             InitHex(hwnd); 
             break;  
                
        /* Handling keys: arrows-- move the black square
        0123456789ABCDEF-- modifying text(hex) in the black square */
        case WM_KEYDOWN:
             switch(wParam)
               {  
 
                  case VK_RIGHT:
                       Invert(hwnd,crx,cry);
                       if(cry<MAX_Y-1)cry++;
                       else {cry=0; if(crx<15) crx++;}
                       Invert(hwnd,crx,cry);
                       left=true;
                       break;
                  case VK_LEFT:
                       Invert(hwnd,crx,cry);
                       if(cry>0){cry--;}
                       else {cry=MAX_Y-1; if(crx>0)crx--;}
                       Invert(hwnd,crx,cry);
                       left=true;
                       break;                       
                  case VK_UP:
                       Invert(hwnd,crx,cry);
                       if(crx>0)crx--;
                       Invert(hwnd,crx,cry);
                       left=true;
                       break;                         
                  case VK_DOWN:
                       Invert(hwnd,crx,cry);
                       if(crx<MAX_X-1)crx++;
                       Invert(hwnd,crx,cry);
                       left=true;
                       break;   

                  case '0': case '1': case '2': case '3': case '4': case '5': case '6':
                  case '7': case '8': case '9': case 'A': case 'B': case 'C': case 'D':
                  case 'E': case 'F':
                       Invert(hwnd,crx,cry);
                       if(left==true) 
                         {
                           left=false;
                           PrintRect(hwnd,(const char)wParam,true);
                           Invert(hwnd,crx,cry);
                           break;
                         }
                       if(left==false)
                         { 
                           left=true;
                           PrintRect(hwnd,(const char)wParam,false);
                           Invert(hwnd,crx,cry);
                           Invert(hwnd,crx,cry);
                           if(cry<16)cry++;
                           else {cry=0; if(crx<16)crx++;};
                           Invert(hwnd,crx,cry);
                         }
                       break;                  
               }
             break;
        case WM_DESTROY:
            PostQuitMessage (0);
            break;
        default:
            return DefWindowProc (hwnd, message, wParam, lParam);
    }
    return 0;
}
/*----------------------------------------------------------------------------*/
// hex.h
/*
How it works:
1. I created an array of rectangles (32x16)
2. Then I arrange rectangles to the window
3. Draw text(hex) to rectangles.
*/
#define MAX_X   32      // 
#define MAX_Y   16      //
#define MARG    15      // left margirn

RECT wnd_rect;           // window rectangle
RECT rect[MAX_X][MAX_Y]; // array of rectangles
bool left=true;          // used when editing hex, tells which one(left or right) character to overwrite
int crx=0,cry=0;         // current rectangle x,y
HFONT  hFont;            // for courier font

/* FUNCTIONS: */
void InitHex(HWND wnd);                                   /* Draws hex fields and sets up the rectangles */
void Invert(HWND wnd,int x,int y);                        /* inverts a rectangle  */
void PrintRect(HWND wnd, const char ch,bool left=true);   /* draws a letter or a number when editing hex */


void InitHex(HWND wnd)
{
   HDC hdc;
   PAINTSTRUCT ps;  
     
   memset(&wnd_rect,0,sizeof(RECT));  
   GetWindowRect(wnd,&wnd_rect);  
   hdc=GetDC(wnd);  
   hdc=BeginPaint(wnd,&ps); 
   
   hFont = CreateFont(4,0,0,0,FW_DONTCARE,FALSE,FALSE,FALSE,DEFAULT_CHARSET,OUT_OUTLINE_PRECIS,
   CLIP_DEFAULT_PRECIS,ANTIALIASED_QUALITY, VARIABLE_PITCH,"Courier");     
   SelectObject(hdc,hFont);
   
int cl=wnd_rect.top-25;   // current line 
int cr=wnd_rect.left+MARG;  // current row

/* this loop will draw the rectangles */
for(int i=0;i<32;i++)
  {

    for(int j=0;j<16;j++)
      {
        rect[i][j].top=cl;        rect[i][j].bottom=cl+15; 
        rect[i][j].left=cr+MARG;       rect[i][j].right=cr+15+MARG; 

        cr+=25;
        DrawTextA(hdc,"00",2,&rect[i][j],DT_VCENTER);    
      }
      cl+=15;
      cr=wnd_rect.left+MARG;
  }
  
   EndPaint(wnd,&ps); 
   ReleaseDC(wnd,hdc);

   Invert(wnd,crx,cry); 
}

void Invert(HWND wnd,int x,int y)
{
    HDC hdc=
        GetDC(wnd);           
    InvertRect(hdc,&rect[x][y]);

    ReleaseDC(wnd,hdc);         
}           


void PrintRect(HWND wnd, const char ch,bool left)
{
    HDC hdc=GetDC(wnd);
   hFont = CreateFont(4,0,0,0,FW_DONTCARE,FALSE,FALSE,FALSE,DEFAULT_CHARSET,OUT_OUTLINE_PRECIS,
   CLIP_DEFAULT_PRECIS,ANTIALIASED_QUALITY, VARIABLE_PITCH,"Courier");     
   SelectObject(hdc,hFont);    
    
    
    if(left==true)      
          TextOut(hdc,rect[crx][cry].left,rect[crx][cry].top,&ch,1);  
    else  
         TextOut(hdc,rect[crx][cry].left+9,rect[crx][cry].top,&ch,1);
         
    ReleaseDC(wnd,hdc);
}

Now the questions:
1. When windows decides the window position I always get the hex fields somewhere not where they mus to be. I think there's something wrong with GetWindowRect().
2. I want to be able to click on a rectangle a invert it then. How can I do this?
3. How can I get text from a rectangle?

Thanks for advice!
here is your code - all in one file (main.cpp) with some corrections - to allow better GDI operation - like the painting of the hex fields.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
#include <windows.h> 
//#include "hex.h"

#define MAX_X   32      // 
#define MAX_Y   16      //
#define MARG    15      // left margirn

RECT wnd_rect;           // window rectangle
RECT rect[MAX_X][MAX_Y]; // array of rectangles
bool left=true;          // used when editing hex, tells which one(left or right) character to overwrite
int crx=0,cry=0;         // current rectangle x,y
//HFONT  hFont;  //No need for global - *******************


WCHAR szClassName[ ] = _T("WindowsApp");

/* FUNCTIONS: */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
void InitHex(HWND wnd);                                   /* Draws hex fields and sets up the rectangles */
void Invert(HWND wnd,int x,int y);                        /* inverts a rectangle  */
void PrintRect(HWND wnd, const char ch,bool left=true);   /* draws a letter or a number when editing hex */


void InitHex(HWND wnd)
{
  HDC hdc;
  PAINTSTRUCT ps;  
  HFONT  hFont, hPFont;  //Put these here - note the extra variable hPFont   

  memset(&wnd_rect,0,sizeof(RECT));  
  //GetWindowRect(wnd,&wnd_rect);  //incorrect
  GetClientRect(wnd,&wnd_rect);  //Notice - GetClientRect  NOT getwindowrect


  //hdc=GetDC(wnd); //Not needed 
  hdc=BeginPaint(wnd,&ps); 

  hFont = CreateFontA(4,0,0,0,FW_DONTCARE,FALSE,FALSE,FALSE,DEFAULT_CHARSET,OUT_OUTLINE_PRECIS,
    CLIP_DEFAULT_PRECIS,ANTIALIASED_QUALITY, VARIABLE_PITCH,"Courier");     

  hPFont = (HFONT)SelectObject(hdc,hFont); //select font  and save old font

  int cl=wnd_rect.top+25;   // current line   notice plus NOT minus 
  int cr=wnd_rect.left+MARG;  // current row

  /* this loop will draw the rectangles */
  for(int i=0;i<32;i++)
  {

    for(int j=0;j<16;j++)
    {
      rect[i][j].top=cl;        rect[i][j].bottom=cl+15; 
      rect[i][j].left=cr+MARG;       rect[i][j].right=cr+15+MARG; 

      cr+=25;
      DrawTextA(hdc,"00",2,&rect[i][j],DT_VCENTER);    
    }
    cl+=15;
    cr=wnd_rect.left+MARG;
  }

  SelectObject(hdc,hPFont); //Do this
  DeleteObject(hFont);//And do this
  EndPaint(wnd,&ps); 
  //ReleaseDC(wnd,hdc); //Not needed

  Invert(wnd,crx,cry); 
}

void Invert(HWND wnd,int x,int y)
{
  HDC hdc=
    GetDC(wnd);           
  InvertRect(hdc,&rect[x][y]);

  ReleaseDC(wnd,hdc);         
}           


void PrintRect(HWND wnd, const char ch,bool left)
{
  HDC hdc=GetDC(wnd);
  HFONT hFont, hPFont;//****Updated
  hFont = CreateFontA(4,0,0,0,FW_DONTCARE,FALSE,FALSE,FALSE,DEFAULT_CHARSET,OUT_OUTLINE_PRECIS,
    CLIP_DEFAULT_PRECIS,ANTIALIASED_QUALITY, VARIABLE_PITCH,"Courier");     
  hPFont=  (HFONT)SelectObject(hdc,hFont);   //**** Updated


  if(left==true)      
    TextOutA(hdc,rect[crx][cry].left,rect[crx][cry].top,&ch,1);  
  else  
    TextOutA(hdc,rect[crx][cry].left+9,rect[crx][cry].top,&ch,1);

  SelectObject(hdc, hPFont);//*******Updated
  DeleteObject(hPFont);//*********Updated

  ReleaseDC(wnd,hdc);
}






int WINAPI WinMain (HINSTANCE hThisInstance,
                    HINSTANCE hPrevInstance,
                    LPSTR lpszArgument,
                    int nFunsterStil)

{
  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 */

  wincl.hInstance = hThisInstance;
  wincl.lpszClassName = szClassName;
  wincl.lpfnWndProc = WindowProcedure;      /* This function is called by windows */
  wincl.style = CS_DBLCLKS;                 /* Catch double-clicks */
  wincl.cbSize = sizeof (WNDCLASSEX);

  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 */
  wincl.hbrBackground = (HBRUSH) COLOR_3DFACE;

  if (!RegisterClassEx (&wincl))
    return 0;

  hwnd = CreateWindowEx (
    WS_EX_CLIENTEDGE,                   /* Extended possibilites for variation */
    szClassName,         /* Classname */
    _T("Windows App"),       /* Title Text */
    WS_OVERLAPPEDWINDOW, /* default window */
    50,       // reik padaryt nepriklausoma nuo situ s.
    40,       
    640,                 /* The programs width */
    600,                 /* and height in pixels */
    HWND_DESKTOP,        /* The window is a child-window to desktop */
    NULL,                /* No menu */
    hThisInstance,       /* Program Instance handler */
    NULL                 /* No Window Creation data */
    );

  ShowWindow (hwnd, nFunsterStil);
  while (GetMessage (&messages, NULL, 0, 0))
  {
    TranslateMessage(&messages);
    DispatchMessage(&messages);
  }
  return messages.wParam;
}

LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
  switch (message)
  {

  case WM_PAINT:
    InitHex(hwnd); 
    break;  


    /* Handling keys: arrows-- move the black square
    0123456789ABCDEF-- modifying text(hex) in the black square */
  case WM_KEYDOWN:
    switch(wParam)
    {  

    case VK_RIGHT:
      Invert(hwnd,crx,cry);
      if(cry<MAX_Y-1)cry++;
      else {cry=0; if(crx<15) crx++;}
      Invert(hwnd,crx,cry);
      left=true;
      break;
    case VK_LEFT:
      Invert(hwnd,crx,cry);
      if(cry>0){cry--;}
      else {cry=MAX_Y-1; if(crx>0)crx--;}
      Invert(hwnd,crx,cry);
      left=true;
      break;                       
    case VK_UP:
      Invert(hwnd,crx,cry);
      if(crx>0)crx--;
      Invert(hwnd,crx,cry);
      left=true;
      break;                         
    case VK_DOWN:
      Invert(hwnd,crx,cry);
      if(crx<MAX_X-1)crx++;
      Invert(hwnd,crx,cry);
      left=true;
      break;   

    case '0': case '1': case '2': case '3': case '4': case '5': case '6':
    case '7': case '8': case '9': case 'A': case 'B': case 'C': case 'D':
    case 'E': case 'F':
      Invert(hwnd,crx,cry);
      if(left==true) 
      {
        left=false;
        PrintRect(hwnd,(const char)wParam,true);
        Invert(hwnd,crx,cry);
        break;
      }
      if(left==false)
      { 
        left=true;
        PrintRect(hwnd,(const char)wParam,false);
        Invert(hwnd,crx,cry);
        Invert(hwnd,crx,cry);
        if(cry<16)cry++;
        else {cry=0; if(crx<16)crx++;};
        Invert(hwnd,crx,cry);
      }
      break;                  
    }
    break;
  case WM_DESTROY:
    PostQuitMessage (0);
    break;
  default:
    return DefWindowProc (hwnd, message, wParam, lParam);
  }
  return 0;
}
Thanks!
Topic archived. No new replies allowed.