الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

تعلم كيف تبرمج Text Editor بالاعتماد على الشاشة السوداء

بدأه The Hidden Ghost في 15 يوليو 2012 · 9 رد · 1,396 مشاهدة · في لغة C و ++C
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

بسم الله الرحمن الرحيم

إن الحمد لله نحمده و نستعينه و نستغفره و نعوذ بالله من شرور أنفسنا و

من سيئات أعمالنا ، من يهده الله فلا مضل له

ومن يضلل فلا هادي له و أشهد أن لا إله إلا الله و أشهد أن محمدا عبده و رسوله صلى الله عليه و على آله و صحبه و سلم .

أما بعد ، فأتقدم بخالص الحب و الوفاء إلى الأستاذ أحمد و الأخ مصطفى اللذين يسهران على إيقاظ المنتدى من سباته الطويل

وذلك من خلال تنشيط القسم فجزاهم الله خير الأجر و الثواب .

سنتطرق في موضوعنا اليوم إلى كيفية برمجة محرر نصوص بسيط في لغة السي بالاعتماد على الكونسول فقط . وعندما أقول بسيط

فأنا أعي تماما ما أقوله لأنني و في أيام خلت كنت أبحث عن فكرة أسترجع فيها فكري البرمجي الضائع :wacko: ، فلا تنتظروا مني محررا كمحرر

Notepad plus plus أو غيره :blush: ، ومع هذا فإني أعدكم تمام الوعد بأن الفكرة ستروق لكم فهيا نشرع في العمل :stop:

1 - ما الذي سنستعمله لتخزين المدخلات ؟؟؟

إن فهمت هذه النقطة بالذات فستسهل عليك برمجة المحرر ، لأنك إن اخترت استعمال الدالة scanf فستكون قد ضللت الطريق بنسبة 99% ،

أنا لا أقول لك أن هذه الدالة لا تصلح في برمجة مثل هذه الأشياء ، لأنه يمكن استخدام هذه الطريقة بإدراج تعليمة استقبال محرف من المستخدم

في حلقة تكرارية و من تم تخزين المحرف في مصفوفة و .... و .... و :hot: . لأ أعتقد أن الطريقة ستكون مجدية البثة لاسيما و أن

الحاسوب صنع لكي ننال من سرعته و خدماته ، لا أن ينال منا و من ضعفنا B) .

بكل بساطة ، نستطيع استخدام دالة من دوال API تستعمل عادة في برمجة KeyLoggers الجميلة :evil: هذه الدالة تسمى

GetAsyncKeyState و التي لها دور فعال في رصد و مراقبة أزرار لوحة المفاتيح ، حيث تعيد لنا قيمة الزر المضغوط :ohmy:



SHORT GetAsyncKeyState(

int vKey // virtual-key code
);


Parameters

vKey

Specifies one of 256 possible virtual-key codes.
Windows NT: You can use left- and right-distinguishing constants to specify certain keys. See the Remarks section for further information.
Windows 95: Windows 95 does not support the left- and right-distinguishing constants available on Windows NT.



Return Values

If the function succeeds, the return value specifies whether the key was pressed since the last call to GetAsyncKeyState, and whether the key is currently up or down. If the most significant bit is set, the key is down, and if the least significant bit is set, the key was pressed after the previous call to GetAsyncKeyState. The return value is zero if a window in another thread or process currently has the keyboard focus.
Windows 95: Windows 95 does not support the left- and right-distinguishing constants. If you call GetAsyncKeyState on the Windows 95 platform with these constants, the return value is zero.

Remarks

You can use the virtual-key code constants VK_SHIFT, VK_CONTROL, and VK_MENU as values for the vKey parameter. This gives the state of the SHIFT, CTRL, or ALT keys without distinguishing between left and right.
Windows NT: You can use the following virtual-key code constants as values for vKey to distinguish between the left and right instances of those keys:

VK_LSHIFT VK_RSHIFT
VK_LCONTROL VK_RCONTROL
VK_LMENU VK_RMENU
The GetAsyncKeyState function determines whether a key is up or down at the time the function is called, and whether the key was pressed after a previous call to GetAsyncKeyState.

2 - برمجة البرنامج : ;)

نلتقي في الرد القادم ...

1
rS3eY.png
#2

بسم الله الرحمن الرحيم ، إليكم الآن سورس كود البرنامج ( البرنامج مازال يحتوي على بعض الأخطاء و إن أردتم المساهمة في انقراضها فسأكون ممتنا لكم ) .

#include <stdio.h>
#include <windows.h>
void ColoringText(short int color); // function for changing text color
main(){
       FILE *f;
       char key;
       f=fopen("untitiled1.txt","w"); // this is the file that we need for storing our text
while(1){
     key++;
     if(GetAsyncKeyState(key)){ // checking which key had pressed
     switch(key){
     case VK_F1:  // F1
          ColoringText(2); //Green
          break;
     case VK_F2: // F2
          ColoringText(14);//Yellow
          break;
     case VK_F3: // F3
          ColoringText(12);//Red
          break;
     case VK_F4: // F4
          ColoringText(11);// Cyan
          break;
     case VK_RETURN: // ENTER
          Sleep(500);
          printf("\n");
          fprintf(f,"%s","\n");
          break;
     case 0x1b: //ESC
          exit(0);
     default:
     /* disable BACkSPACE */
     if(key == '\b'){
     fprintf(f,"%s","""");
     break;
     }
      /* disable LEFT SHIFT & RIGHT SHIFT  */
     else if(key == VK_SHIFT){
     fprintf(f,"%s","""");
     break;
     }
     /* disable ALT*/
     else if(key == VK_MENU){
     fprintf(f,"%s","""");
     break;
     }
     Sleep(500);
     printf("%c",key);
     fprintf(f,"%c",key); // write the character whithin the file .
     break;
     }
}
}
}
void ColoringText(short int color){
     HANDLE hconsole=GetStdHandle(STD_OUTPUT_HANDLE);
     SetConsoleTextAttribute(hconsole,color);
}

النص يحفظ تلقائيا في ملف اسمه untitled1.txt كما يمكنك تغيير لون الكتابة بالضغط على F1 , F2 , F3 , F4 تباعا :haha:

أتمنى أن أكون قد وفقت في طرح الموضوع و عذرا لأنني لم أسهب في الشرح لأنني و كما تعلمون ما زلت مبتدئا :wink: ...

HQTextEditor.zip

1
rS3eY.png
#3

بارك الله فيك أخي حمزة ...

ما رأيك أن أهديك كود سيساعدك كثيراً في ما تريد الوصول له ....... (ملاحظة الكود من كتابة الأخ keepforward إذا كنت تتذكره )

// this parnameg by OMAR ALKATTAN



#include <iostream.h>
#include <windows.h>

static int n=1,n_some=0,n_double=0,k_event_ct,count=0;

void gotoxy(int ,int);

void keys(KEY_EVENT_RECORD); 
void mouse(MOUSE_EVENT_RECORD); 
//void event(WINDOW_BUFFER_SIZE_RECORD); 
void main()
{
	HANDLE h = GetStdHandle(STD_INPUT_HANDLE);
	INPUT_RECORD input[250];
	DWORD ct,enable;

	enable	= ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT;	

	SetConsoleMode(h,enable);

	cout<<"\nMouse Events :\n\nKeys Events :"<<flush;

	for(;;)
	{
		int i=0;
		ReadConsoleInput(h, &input, 250, &ct);
		/*
	ReadConsoleInputA(
	HANDLE hConsoleInput,
	PINPUT_RECORD lpBuffer,
	DWORD nLength,
	LPDWORD lpNumberOfEventsRead
	);
		typedef struct _INPUT_RECORD {
	WORD EventType;
	union {
    	KEY_EVENT_RECORD KeyEvent;
    	MOUSE_EVENT_RECORD MouseEvent;
    	WINDOW_BUFFER_SIZE_RECORD WindowBufferSizeEvent;
    	MENU_EVENT_RECORD MenuEvent;
    	FOCUS_EVENT_RECORD FocusEvent;
	} Event;
} INPUT_RECORD, *PINPUT_RECORD;
		typedef struct _KEY_EVENT_RECORD {
	BOOL bKeyDown;
	WORD wRepeatCount;
	WORD wVirtualKeyCode;
	WORD wVirtualScanCode;
	union {
    	WCHAR UnicodeChar;
    	CHAR   AsciiChar;
	} uChar;
	DWORD dwControlKeyState;
} KEY_EVENT_RECORD, *PKEY_EVENT_RECORD;
		typedef struct _MOUSE_EVENT_RECORD {
	COORD dwMousePosition;
	DWORD dwButtonState;
	DWORD dwControlKeyState;
	DWORD dwEventFlags;
} MOUSE_EVENT_RECORD*/
		gotoxy(count,0);cout<<(char)count<<flush;
		if(ct>0)
		{

			if(input.EventType	==	MOUSE_EVENT	)
				mouse(input.Event.MouseEvent);	

			else if (input.EventType	==	KEY_EVENT )
			{
				k_event_ct	=	input.Event.KeyEvent.wVirtualKeyCode;
				input[k_event_ct]	=	input;
				keys(input[k_event_ct].Event.KeyEvent);
			}
		}
		/*	gotoxy(0,0);
			if(count%2==0) cout<<"4"<<flush;
			else	cout<<"R"<<flush;*/ 
			++count;
	}


}


void mouse(MOUSE_EVENT_RECORD M)
{
	if(M.dwEventFlags	==	0)
	{
		if(M.dwButtonState	== FROM_LEFT_1ST_BUTTON_PRESSED)
		{	gotoxy(25,1);	cout<<"+ left button "<<flush;	}

		else if(M.dwButtonState	== RIGHTMOST_BUTTON_PRESSED)
		{	gotoxy(25,1);	cout<<"+ right button"<<flush;	}

		else
		{	gotoxy(25,1); ++n_some;	cout<<"+ some button "<<n_some<<flush;	}
	}

	else if(M.dwEventFlags	==	DOUBLE_CLICK)
	{
		gotoxy(45,1);	++n_double;	cout<<"+ double click "<<n_double<<flush;	
	}

	else if(M.dwEventFlags	==	MOUSE_MOVED)
	{	gotoxy(65,1);
		if(n%3==0)	cout<<"  *"<<flush;	
		else if(n%2==0)	cout<<" * "<<flush;
		else cout<<"*  "<<flush;
		++n;

		gotoxy(15,1);	cout<<"("<<M.dwMousePosition.X<<","<<M.dwMousePosition.Y<<")"<<flush;
	}
	else
	{
		gotoxy(15,5); cout<<"k"<<flush;
	}
}


void keys(KEY_EVENT_RECORD	K)
{
	//gotoxy(15,K.wVirtualKeyCode);
	if(K.bKeyDown)
	{
	/*	if( k_event_ct == 17 )	{*/	gotoxy(5,k_event_ct); cout<<k_event_ct<<flush;//	}
	/*	else if(	k_event_ct == 16 )	{	gotoxy(5,5);	cout<<"Shift"<<flush;	}
		else if(	k_event_ct == 32 )	{	gotoxy(12,5);	cout<<"Space"<<flush;	}
		else	{ gotoxy(18,5);	cout<<k_event_ct<<flush;	}*/
	}
	else
	{
	/*	if( k_event_ct == 17 )	{*/	gotoxy(5,k_event_ct); cout<<"       	"<<flush;//	}
	/*	else if(	k_event_ct == 16 )	{	gotoxy(5,5);	cout<<" 	"<<flush;	}
		else if(	k_event_ct == 32 )	{	gotoxy(12,5);	cout<<" 	"<<flush;	}
		else	{ gotoxy(18,5);	cout<<"   "<<flush;	}*/
	}


}




void gotoxy(int x, int y) // ÊÇÈÚ áÊÍÑíß ÇáãÄÔÑ æÇáØÈÇÚÉ ãä Êáß ÇáãäØÞÉ
{ 
	COORD pos = {x, y};
	HANDLE output = GetStdHandle(STD_OUTPUT_HANDLE);
	SetConsoleCursorPosition(output, pos);
}

أرجو أن يعجبك ... والسلام عليكم ورحمة الله وبركاته ..

1
#4

مشكور أخي مصطفى على المرور + أظن أن السورس كود الذي أعطيتني يتحكم في في أحداث مؤشر الفأرة ، أ ليس كذلك ؟؟؟؟

rS3eY.png
#5
Hamza+C+ASM كتب:

مشكور أخي مصطفى على المرور + أظن أن السورس كود الذي أعطيتني يتحكم في في أحداث مؤشر الفأرة ، أ ليس كذلك ؟؟؟؟

نعم هو كذلك كما أنه يتحكم في أحداث الكيبورد لغاية ضغط خمس أزرار معاً ... من ضمنها أزرار التحكم مثل shift وalt وF1,2,3,4...

أظن أن هذه الطريقة أسهل في الإدخال ... خصوصاً .. بالنسبة لمشروعك ..

(اعذرني على عدم قراءة الكود ... فعندي امتحان يوم الخميس وأرتب أولوياتي بصعوبة ... المعذرة )

بالتوفيق

تم تعديل هذه المشاركة بواسطة مصطفى 36a2 في 15 يوليو 2012 في 16:32

#6

ليس هناك أي مشكل أخي مصطفى :lol: + الله يوفقك في الإمتحان إن شاء الله + عندما تنتهي من الإمتحانات أكتب لنا موضوعا من مواضيعك

الساحرة و الجميلة :)

السلام عليكم ورحمة الله تعالى و بركاته ،،،

rS3eY.png
#7

السلام عليكم

مرحبا أخي حمزة :)

أعتقد أن الكود ما زال ينقصه العديد من الأشياء حتى نستطيع أن نُسميه "محرر نصوص تقليدي" !!

إضافة إلى ذلك, يجب عليك مراعاة إظهار المُدخلات, فالرموز الغير مرئية مثلا, يجب أن لا تظهر, نفس الشيء بالنسبة لرموز التحكم.

قمتُ بكتابة هذا الكود الذي يمكن أن يُساعدك في عملية الإدخال :

#include<stdio.h>
#include<conio.h>
#include<ctype.h>

int GetChar() {
    int ch = getch();
    while (ch == 0 || ch == 224) {
        getch();
        ch = getch();
    }
    return ch;
}

int main(int argc, char *argv[]) {
    char key;
    int count = 0;
    while (key = GetChar()) {
        if (!iscntrl(key)) {
            printf("%c", key);
            if (key == '-') count = 0;
            else {
                count++;
                continue;
            }
        } else if ((key != (char) 13 && key != ' ')) continue;

        if ((key == (char) 13 || key == ' ') && !count) break;
        else if (count) {
            key == 13 ? printf("\n") : printf(" ");
        }
        if (count >= 2) count = 0;
    }
    return 0;
}

  • البرنامج لا يقبل إدخال الرموز الغير مرئية (الأسهم,tab,ESC,F1,F2, ... , F12).
  • لإنهاء الكتابة, أدخل - ثم اضغط على Enter.
  • يمكنك تكملة الكود حتى يدعم إدخال الـ Backspace لأنه يعتبرها الآن من الرموز الغير مرئية.

هناك ملاحظة أخيرة, لمَ لمْ تستدعي الدالة fclose حتى تُغلق الملف ؟

1
#8

أخي أحمد ، لقد جربت برنامجك لكن الشيء الذي لم يعجبني فيه والذي جعلني أنأى عن هذه الطريقة هو محدودية

النص ، بكلمة أخرى هل يمكننا كتابة نصوص كبيرة بهذه الطريقة أخي أحمد ؟ لقد كتبت الرقم 224 الذي يمثل عدد الحروف التي سوف تخزن ،

هل يمكننا تخزين عدد كبيــــــــــــــر جدا ؟

بالنسبة لسؤالك ، لقد نسيت إغلاق الملف :S .

لم تضع كيفية تصدير النص إلى ملف خارجي ، أرجو أن تضعها لأستفيد أكثر مما أستفيده من مواضيعك الجميلة :lol:

rS3eY.png
#9
اقتباس
لقد كتبت الرقم 224 الذي يمثل عدد الحروف التي سوف تخزن

من أين لك بهذا الكلام أخي حمزة ؟ :D

الدالة GetChar تكمن مهمتها في تجنب الازرار F1, F2,... والاسهم و الحروف الغير مرئية, فاذا كان الحرف سهما أو F1,... فان النظام يرسل حرفين احدهما 0 أو 224 ثم يتبعه بحرف آخر (لذا تجد انك اذا ضغطت على ازرار الأسهم سيكتب لك حروفا مثل H, M, K ... فالحرف الأول غير مرئي [0 أو 224 ] و الحرف الثاني هو الذي ظهر وهذا ما لا تريده انت في برنامجك, اذن يجب التخلص من الحرف الثاني إذا كان الاول يساوي 0 أو 224 و بذلك تعالج الاسهم و F1, F2,... ).

1
#10

لا تكثرت لي فأنا غبي كما تعلم ، لم أدقق جيدا في السورس لكي أفهمه :lol:

rS3eY.png

مواضيع مشابهة

عدد الزوار حالياً

المتواجدون خلال آخر دقيقتين · يتحدّث كل ٣٠ ثانية

—الإجمالي—أعضاء مسجّلون—زوار بدون تسجيل

جارٍ التحقق من المتواجدين…