Почему переменная HWND hwnd объявлена дважды: один раз в начале функции WinMain —
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{ HWND hwnd; // дескриптор окна
...
и второй раз в функции WndProc —
LONG WINAPI WndProc(HWND hwnd;, UINT Message, WPARAM wparam, LPARAM lparam)
...
Это код из минимального оконного приложения на WinAPI, после запуска появляется окно:

Это разные переменные. Одну переменную нельзя объявить дважды.
Прежде чем изучать Windows API, надо изучить язык программирования C или C++.
Первый HWND hwnd и есть дескриптор создаваемого окна.
Можно понаделать
HWND hwnd1 = CreateWindow(...
HWND hwnd2 = CreateWindow(...
HWND hwnd3 = CreateWindow(...
WndProc - это callback фукнкция. Окно работает в ином потоке чем сама программа. Тот поток смотрит что за действия были сделаны и потом посылает сообщение,
грубо говоря делает так
int num_of_windows = GetNumOfCreatedWindows(); // 3 окна мы сделали
for( int i = 0; i < num_of_windows; ++i ){
HWND hWnd = GetCreatedWindowById( i );
if( GetWindowMessage( hWnd ) ){ // если есть какое сообщение
WndProc( hWnd, 1, 0, 0 ); // посылаем какое-то сообщение в программу
}
}
=============================
В самой функции можно написать
тут hwnd = параметр
LONG WINAPI WndProc(HWND hwnd;, UINT Message, WPARAM wparam, LPARAM lparam)
{
if( hwnd == hWnd1 ) printf( "Это первое окно\n" );
if( hwnd == hWnd2 ) printf( "Это второе окно\n" );
if( hwnd == hWnd3 ) printf( "Это третье окно\n" );
}
то дескриптор главного окна приложения, а то дескриптор окна к которому привязана windproc
Почитай про область видимости переменных, есть глобальные переменные, есть локальные. Из функции WinMain() вторую перемененную hwnd из WinProc() не видно и наоборот. Следовательно, локальные переменные из разных функций модно называть одним и тем же именем. Всё остальное нельзя. (С приставкой static это уже отдельная тема)